我更改了各种控件的突出显示颜色,并且我打算进行更多更改。因此,尽管我最好创建自己的控件并重用它们,而不是对每个控件进行更改。
我创建了一个新的用户控件,并继承自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();
}
}
您可能会在扩展自定义设置时考虑公开更多属性,因此可以根据需要为每个实例更改它们。
也不要忘记处理您创建的GDI对象,例如画笔和笔!
编辑:刚刚注意到BackColor
将隐藏原始属性。将其更改为SelectedBackColor
,实际上表明了它的含义!
Edit 2:正如Simon在评论中指出的那样,有一种HasFlag
方法,因此从.Net 4.0开始,还可以编写:
Brush brush = ((e.State.HasFlag(DrawItemState.Selected) ?
更清晰,更短。
Edit 3:实际上,建议在控件上使用TextRenderer.DrawText
,而不要使用graphics.DrawString
。
感谢这篇有用的帖子。我做了一个小的改进,其他人可能会觉得有用。
当ComboBox的DisplayMember属性设置为访问所显示项目的特定属性时,ToString()可能不会提供期望的文本。解决方法是使用:
GetItemText(Items[e.Index])
在对DrawString()的调用中检索所需的文本。