C# 覆盖组合框的DrawItem

C# 覆盖组合框的DrawItem,c#,inheritance,combobox,controls,ondraw,C#,Inheritance,Combobox,Controls,Ondraw,我更改了各种控件的高光颜色,并计划进行更多更改。因此,我认为最好创建自己的控件并重用它们,而不是对每个控件都进行更改 我创建了一个新的用户控件,并继承了System.Windows.Forms.ComboBox。 问题是我找不到一种方法来覆盖onDraw,就像我在onClick中那样 那我怎么去推翻它呢?下面是我为每个控件onDraw事件使用的代码 public void comboMasterUsers_DrawItem(object sender, DrawItemEventArgs e)

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

我创建了一个新的用户控件,并继承了
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();
    }
谢谢

给你:

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();
    }
}

您可以考虑在扩展CuffiZIZE时暴露更多的属性,这样您就可以在每个实例中更改它们。 也别忘了处理你创建的GDI对象,比如画笔和钢笔

Edit:刚刚注意到
BackColor
会隐藏原始属性。将其更改为
SelectedBackColor
,它实际上说明了它是什么

编辑2:正如Simon在评论中指出的那样,有一个
HasFlag
方法,从.Net 4.0开始,人们还可以编写:

      Brush brush = ((e.State.HasFlag(DrawItemState.Selected) ?
这是一个更清晰,更短的


编辑3:实际上,对于绘制到控件上的控件,请使用
文本渲染器。建议使用DrawText
而不是
graphics.DrawString

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

当组合框的DisplayMember属性设置为访问显示项的特定属性时,ToString()可能不会给出预期的文本。解决此问题的方法是使用:

    GetItemText(Items[e.Index])

要在调用DrawString()时检索所需的文本,我尝试并修复了ComboBox 1的comboMasterUsers。 示例:

public void组合框1\u DrawItem(对象发送方,DrawItemEventArgs e)
{
e、 牵引杆接地();
图形g=e.图形;
笔刷笔刷=((e.State&DrawItemState.Selected)=DrawItemState.Selected)?
笔刷。LightSeaGreen:新的SolidBrush(例如背景色);
g、 圆角矩形(画笔,例如边界);
e、 Graphics.DrawString(comboBox1.Items[e.Index].ToString(),e.Font,
新的SolidBrush(e.ForeColor)、e.Bounds、StringFormat.GenericDefault);
e、 DrawFocusRectangle();
}
我看到了:

谢谢,它很管用。但有一个问题。当我将DropDownStyle更改为DropDownList时,有一个错误:InvalidArgument=值-1对索引无效请参阅我的小更正wrt tBrush!GDI对象有一种可怕的倾向,就是悄悄地泄漏..还有另一个小小的修正;-)我没有注意到这个警告,但现在看起来没问题。简而言之,悲伤的故事:画笔、钢笔和位图都很特别。它们不是GC收集的普通c#对象;它们是分开存放的,您有责任处理它们。90年代的GDI传统哦我明白了。。谢谢你的信息!