且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

在焦点上更改组合框的边框颜色

更新时间:2023-12-06 12:58:58

这是一个简单的类,它继承自 ComboBox 并公开了两个允许设置控件的活动和非活动边框的属性.

This is a simple Class that inherits from ComboBox and exposes two properties that allows to set the Active and Inactive border of the Control.

使用父窗体 Paint() 事件完成绘制,仅使所选控件周围的区域无效.

The painting is done using the Parent Form Paint() event, invalidating only the area around the selected control.

Parent Paint() 事件在自定义 ComboBox OnHandleCreated() 事件中订阅,连同控件的 Enter()Leave()Move() 事件.
需要订阅Move() 事件才能绘制透明边框,否则在设计时拖动控件时边框将保持绘制在父客户区.

The Parent Paint() event is subscribed in the custom ComboBox OnHandleCreated() event, along with the control's Enter(), Leave() and Move() events.
Subscribing the Move() event is required to paint a transparent border, otherwise the border will remain painted on the Parent client area while dragging the control at Design time.

我还添加了 DropDownBackColor()DropDownForeColor() 属性,如果自定义 ComboBox DrawMode 设置为 OwnerDrawVariable(像往常一样).

I've also added DropDownBackColor() and DropDownForeColor() properties, which become active if the custom ComboBox DrawMode is set to OwnerDrawVariable (as usual).

这是它的样子:

This is how it looks like:


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