【发布时间】:2011-12-17 04:05:55
【问题描述】:
我创建了一个自定义comboBox,它支持项目文本前面的图像。这是它的外观:
为此,我创建了一个名为 ImageComboBox 的新控件,该控件存储在我的 winforms 项目中引用的 dll 中。
这个ImageComboBox 只不过是一个ComboBox,其中DrawMode 设置为DrawMode.OwnerDrawFixed,并持有一个包含所有要绘制的图像的ImageList。有一个DrawItemEventHandler负责绘制每个item的图片和文字。
我遇到了一个两像素问题,但令人困惑的是问题并不总是发生。当我创建一个新的 winforms 项目并简单地添加一个新的ImageComboBox 时,我没有问题。当我在相当高级的 winforms 项目上添加新的ImageComboBox 时,会出现问题 - 10 次中有 9 次(或类似的情况)。
这是重现我的两像素问题的步骤:
- 当我打开表单时,一切正常:
- 当我放下
imageComboBox时,一切都很好:
- 当我悬停一个项目以选择它时,一切都很好:
- 当我选择一个项目时,一切都很好:
- 当我下拉
imageComboBox时,当有一个项目被选中时,就会出现问题:所选项目前面的图像向右移动了两个像素,文本向左移动了一个像素:
让我们放大: - 这里证明了我有时没有这个错误:
让我们再次放大:
这是我的ImageComboBox 的DrawItemEvent:
(this._imageList 是我的ImageList 对象)
private void OnDrawItem(object sender, DrawItemEventArgs e) {
if (e.Index >= 0) {
// If the current item is one in the comboBox
// Compute the X location of the text to drawn
int strLocationX = this._imageList.Images.Count > e.Index ?
this._imageList.Images[e.Index].Width + 1 :
e.Bounds.X + 1;
// Get the displayed text of the current item
String itemText = this.Items[e.Index].ToString();
if (this.DroppedDown) {
// If the comboBox is dropped down
// Draw the blue rectangle
e.DrawBackground();
if (e.State == DrawItemState.ComboBoxEdit) {
// If we are drawing the selected item
// Draw the text
e.Graphics.DrawString(itemText, this.Font, Brushes.Black,
new Point(strLocationX + 1, e.Bounds.Y + 1));
if (this._imageList.Images.Count > e.Index) {
// If we have an image available
// Draw the image
e.Graphics.DrawImage(this._imageList.Images[e.Index],
new Point(e.Bounds.X, e.Bounds.Y - 1));
}
} else {
// If we are drawing one of the item in the drop down
// Check if the item is being highlighted
if (e.State.ToString().Contains(DrawItemState.Focus.ToString()) &&
e.State.ToString().Contains(DrawItemState.Selected.ToString())) {
// Draw the text in White
e.Graphics.DrawString(itemText, this.Font, Brushes.White,
new Point(strLocationX, e.Bounds.Y + 1));
} else {
// Draw the text in Black
e.Graphics.DrawString(itemText, this.Font, Brushes.Black,
new Point(strLocationX, e.Bounds.Y + 1));
}
if (this._imageList.Images.Count > e.Index) {
// If we have an image available
// Draw the image
e.Graphics.DrawImage(this._imageList.Images[e.Index],
new Point(e.Bounds.X + 2, e.Bounds.Y - 1));
}
}
} else {
// If the comboBox is not dropped down
// Draw the text
e.Graphics.DrawString(itemText, this.Font, Brushes.Black,
new Point(strLocationX + 1, e.Bounds.Y + 1));
if (this._imageList.Images.Count > e.Index) {
// If we have an image available
// Draw the image
e.Graphics.DrawImage(this._imageList.Images[e.Index],
new Point(e.Bounds.X, e.Bounds.Y - 1));
}
}
}
}
在我看来,代码应该是正确的,但似乎有时if 条件不会返回相同的结果,而我认为它应该这样做。
关于这个问题可能来自哪里的任何线索?
【问题讨论】:
标签: c# winforms events combobox