覆盖ComboBox的DrawItem

时间:2014-06-29 11:50:06

标签: c# inheritance combobox controls ondraw

我更改了各种控件的高亮颜色,我打算进行更多更改。因此,我最好创建自己的控件并重用它们,而不是为每个控件进行更改。

我创建了一个新的用户控件,并继承自System.Windows.Forms.ComboBox。 问题是我无法像onDraw那样找到覆盖onClick的方法。

那我该如何去改写呢?以下是我用于每个控件onDraw事件

的代码
public void comboMasterUsers_DrawItem(object sender, DrawItemEventArgs e)
    {
        e.DrawBackground();

        Graphics g = e.Graphics;
        Brush brush = ((e.State & DrawItemState.Selected) == DrawItemState.Selected) ?
                      Brushes.LightSeaGreen : new SolidBrush(e.BackColor);

        g.FillRectangle(brush, e.Bounds);
        e.Graphics.DrawString(comboMasterUsers.Items[e.Index].ToString(), e.Font,
                 new SolidBrush(e.ForeColor), e.Bounds, StringFormat.GenericDefault);

        e.DrawFocusRectangle();
    }

谢谢!

3 个答案:

答案 0 :(得分:4)

你走了:

public class myCombo : ComboBox
{
    // expose properties as needed
    public Color SelectedBackColor{ get; set; }

    // constructor
    public myCombo()
    {
        DrawItem += new DrawItemEventHandler(DrawCustomMenuItem);
        DrawMode = System.Windows.Forms.DrawMode.OwnerDrawFixed;
        SelectedBackColor= Color.LightSeaGreen;
    }

    protected  void DrawCustomMenuItem(object sender, DrawItemEventArgs e)
    {
        e.DrawBackground();
         // a dropdownlist may initially have no item selected, so skip the highlighting:
        if (e.Index >= 0) 
        {  
          Graphics g = e.Graphics;
          Brush brush = ((e.State & DrawItemState.Selected) == DrawItemState.Selected) ?
                         new SolidBrush(SelectedBackColor) : new SolidBrush(e.BackColor);
          Brush tBrush = new SolidBrush(e.ForeColor);

          g.FillRectangle(brush, e.Bounds);
          e.Graphics.DrawString(this.Items[e.Index].ToString(), e.Font,
                     tBrush, e.Bounds, StringFormat.GenericDefault);
          brush.Dispose();
          tBrush.Dispose();
        }
        e.DrawFocusRectangle();
    }
}

您可以考虑在展开自定义时公开更多属性,以便在需要时为每个实例更改它们。

另外,不要忘记处理您创建的GDI对象,如画笔和笔!

修改:注意BackColor会隐藏原始属性。将其更改为SelectedBackColor,实际上说它是什么!

编辑2:正如Simon在评论中指出的那样,有HasFlag方法,因此.Net 4.0也可以写:

      Brush brush = ((e.State.HasFlag(DrawItemState.Selected) ?

更清晰,更短。

答案 1 :(得分:0)

感谢这篇有用的帖子。我做了一个小的改进,其他人可能会觉得有用。

当ComboBox的DisplayMember属性设置为访问所显示项目的特定属性时,ToString()可能不会提供预期的文本。解决方法是使用:

    GetItemText(Items[e.Index])

在对DrawString()的调用中检索所需的文本。

答案 2 :(得分:-1)

我尝试将 comboMasterUsers 修复为 comboBox1。 示例:

    public void comboBox1_DrawItem(object sender, DrawItemEventArgs e)
    {
        e.DrawBackground();

        Graphics g = e.Graphics;
        Brush brush = ((e.State & DrawItemState.Selected) == DrawItemState.Selected) ?
                      Brushes.LightSeaGreen : new SolidBrush(e.BackColor);

        g.FillRectangle(brush, e.Bounds);
        e.Graphics.DrawString(comboBox1.Items[e.Index].ToString(), e.Font,
                 new SolidBrush(e.ForeColor), e.Bounds, StringFormat.GenericDefault);

        e.DrawFocusRectangle();
    }

我看到了: The sample