【问题标题】:Custom ImageComboBox not always behaving the same way自定义 ImageComboBox 的行为方式并不总是相同
【发布时间】:2011-12-17 04:05:55
【问题描述】:

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

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

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


这是重现我的两像素问题的步骤:

  1. 当我打开表单时,一切正常:
  2. 当我放下imageComboBox 时,一切都很好:
  3. 当我悬停一个项目以选择它时,一切都很好:
  4. 当我选择一个项目时,一切都很好:
  5. 当我下拉imageComboBox时,当有一个项目被选中时,就会出现问题:所选项目前面的图像向右移动了两个像素,文本向左移动了一个像素:

    让我们放大:
  6. 这里证明了我有时没有这个错误:

    让我们再次放大:

这是我的ImageComboBoxDrawItemEvent
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


    【解决方案1】:

    找到答案:代码不对,我在sn-p开头有一个错误的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
    
            // ...
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-01-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-06
      • 1970-01-01
      • 2023-02-14
      相关资源
      最近更新 更多