自定义ImageComboBox并不总是以相同的方式运行

时间:2011-10-28 09:36:18

标签: c# winforms events combobox

我创建了一个自定义comboBox,支持项目文本前面的图像。以下是它的外观: ImageComboBox

为此,我创建了一个名为ImageComboBox的新控件,该控件存储在我的winforms项目中引用的dll中。 此ImageComboBox只是ComboBoxDrawMode设置为DrawMode.OwnerDrawFixed并持有ImageList,其中包含要绘制的所有图片。有DrawItemEventHandler负责绘制图像和每个项目的文本。

我遇到了一个两像素问题,但令人困惑的部分是问题并非总是发生。当我创建一个新的winforms项目并简单地添加一个新的ImageComboBox时,我没有问题。当我在一个相当高级的winforms项目上添加一个新的ImageComboBox时,会出现问题 - 在10次中有9次(或类似的事情)。


以下是重现我的双像素问题的步骤:

  1. 当我打开表格时,一切都很好:
    First step
  2. 当我放下imageComboBox时,一切都很好:
    Second step
  3. 当我悬停一个项目来选择它时,一切都很好:
    Third step
  4. 当我选择一个项目时,一切都很好:
    Fourth step
  5. 当我选择一个项目时,我下拉imageComboBox时会出现问题:所选项目前面的图像右移两个像素,文本移动一个像素左边:
    Fifth step
    我们来缩放: Fifth step - zoomed
  6. 这里证明我有时没有这个错误:
    Fifth step - no bug
    让我们再次放大:
    Fifth step - no bug - zoomed

  7. 以下是我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)); } } } } 条件不会返回相同的结果,而我认为应该这样做。

    有关此问题可能来自哪里的任何线索?

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

        // ...