我创建了一个自定义comboBox
,支持项目文本前面的图像。以下是它的外观:
为此,我创建了一个名为ImageComboBox
的新控件,该控件存储在我的winforms项目中引用的dll
中。
此ImageComboBox
只是ComboBox
,DrawMode
设置为DrawMode.OwnerDrawFixed
并持有ImageList
,其中包含要绘制的所有图片。有DrawItemEventHandler
负责绘制图像和每个项目的文本。
我遇到了一个两像素问题,但令人困惑的部分是问题并非总是发生。当我创建一个新的winforms项目并简单地添加一个新的ImageComboBox
时,我没有问题。当我在一个相当高级的winforms项目上添加一个新的ImageComboBox
时,会出现问题 - 在10次中有9次(或类似的事情)。
以下是重现我的双像素问题的步骤:
imageComboBox
时,一切都很好:imageComboBox
时会出现问题:所选项目前面的图像右移两个像素,文本移动一个像素左边:以下是我DrawItemEvent
的{{1}}:
(ImageComboBox
是我的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));
}
}
}
}
条件不会返回相同的结果,而我认为应该这样做。
有关此问题可能来自哪里的任何线索?
答案 0 :(得分:0)
找到答案:代码不正确,我在代码段的开头有一个错误的if
条件(但我仍然不明白为什么有时会发生错误,有时候不会发生错误)。
我必须使用:
if (this.DroppedDown) {
// If the comboBox is dropped down
// Draw the blue rectangle
e.DrawBackground();
if (( e.State & DrawItemState.ComboBoxEdit ) == DrawItemState.ComboBoxEdit) {
// If we are drawing the selected item
// ...
而不是:
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
// ...