这是一个简单的类,它继承自 ComboBox,并公开了两个允许设置控件的活动和非活动边框的属性。
使用父窗体Paint() 事件完成绘制,仅使选定控件周围的区域无效。
在自定义组合框OnHandleCreated() 事件中订阅了父Paint() 事件,以及控件的Enter()、Leave() 和Move() 事件。
绘制透明边框需要订阅Move() 事件,否则在设计时拖动控件时,边框将保持绘制在父客户区。
我还添加了DropDownBackColor() 和DropDownForeColor() 属性,如果自定义组合框DrawMode 设置为OwnerDrawVariable(像往常一样),它们将变为活动状态。
看起来是这样的:
public class CustomCombo : ComboBox
{
private Color ActionBorderColor = Color.Empty;
public CustomCombo()
{
InitializeComponent();
}
public Color BorderActive { get; set; }
public Color BorderInactive { get; set; }
public Color DropDownBackColor { get; set; }
public Color DropDownForeColor { get; set; }
private void InitializeComponent()
{
this.DrawMode = DrawMode.OwnerDrawVariable;
this.BorderActive = Color.OrangeRed;
this.BorderInactive = Color.Transparent;
this.DropDownBackColor = Color.FromKnownColor(KnownColor.Window);
this.DropDownForeColor = this.ForeColor;
this.HandleCreated += new EventHandler(this.OnControlHandle);
}
protected void OnControlHandle(object sender, EventArgs args)
{
Form parent = this.FindForm();
parent.Paint += new PaintEventHandler(this.ParentPaint);
this.Enter += (s, ev) => { this.InvalidateParent(BorderActive); };
this.Leave += (s, ev) => { this.InvalidateParent(BorderInactive); };
this.Move += (s, ev) => { this.InvalidateParent(Color.Transparent); };
base.OnHandleCreated(e);
}
private void InvalidateParent(Color bordercolor)
{
ActionBorderColor = bordercolor;
Rectangle rect = this.Bounds;
rect.Inflate(2, 2);
this.FindForm().Invalidate(rect);
}
protected void ParentPaint(object sender, PaintEventArgs e)
{
Rectangle rect = this.Bounds;
rect.Inflate(1, 1);
using (Pen pen = new Pen(ActionBorderColor, 1))
e.Graphics.DrawRectangle(pen, rect);
}
protected override void OnDrawItem(DrawItemEventArgs e)
{
using (SolidBrush bkBrush = new SolidBrush(this.DropDownBackColor))
e.Graphics.FillRectangle(bkBrush, e.Bounds);
using (SolidBrush foreBbrush = new SolidBrush(this.DropDownForeColor))
e.Graphics.DrawString(this.Items[e.Index].ToString(),
this.Font, foreBbrush, new PointF(e.Bounds.X, e.Bounds.Y));
e.DrawFocusRectangle();
}
}