在自定义控件中两次调用Control.OnPaint()

时间:2018-08-21 17:32:13

标签: c# visual-studio winforms

我是自定义控件的新手。我正在尝试创建一个平面Button,当鼠标或键盘焦点移到它时,它会更改其边框颜色和文本颜色。

当我从设计器中更改BorderColor的{​​{1}}属性时,它不会更新颜色,并且在我运行程序时,Button仍保持不变。 />

我不确定我编写的BorderColor事件代码。首次运行时,控制台两次退出。我不知道为什么!

如何制作自定义控件,以便可以在Designer中摆弄其属性?

OnPaint()

1 个答案:

答案 0 :(得分:1)

我稍微修改了您的原始类,添加了一些私有字段来跟踪Button控件的当前状态。

用:OnEnter()OnLeave()代替了OnGotFocus()OnLostFocus()

添加了一些引用当前文本和边框颜色的私有字段,这些私有字段是在Button Click()事件上修改的,输入控件时或输入焦点离开时的。

private Color m_CurrentBorderColor;
private Color m_CurrentTextColor;

此外,每次更改属性时,都会调用Invalidate()方法,该方法引发Control的OnPaint()事件,从而更新其外观。

其他细微变化。

class FlatButton : Control
{
    private Color m_TextColor;
    private Color m_BorderColor;
    private Color m_ActiveBorderColor;
    private Color m_ActiveTextColor;
    private Color m_CurrentBorderColor;
    private Color m_CurrentTextColor;

    public override Cursor Cursor { get; set; } = Cursors.Hand;
    public float BorderThickness { get; set; } = 2;
    public Color BorderColor {
        get => this.m_BorderColor;
        set { this.m_BorderColor = value;
              this.m_CurrentBorderColor = value;
              this.Invalidate();
        }
    }
    public Color TextColor {
        get => this.m_TextColor;
        set {
            this.m_TextColor = value;
            this.m_CurrentTextColor = value;
            this.Invalidate();
        }
    }
    public Color ActiveBorderColor { get => this.m_ActiveBorderColor; set { this.m_ActiveBorderColor = value; } }
    public Color ActiveTextColor { get => this.m_ActiveTextColor; set { this.m_ActiveTextColor = value; } }

    private StringFormat stringFormat;

    public FlatButton()
    {
        this.m_TextColor =  ColorTranslator.FromHtml("#0047A0");
        this.m_BorderColor = ColorTranslator.FromHtml("#0047A0");
        this.m_ActiveBorderColor = ColorTranslator.FromHtml("#158C3F");
        this.m_ActiveTextColor = ColorTranslator.FromHtml("#158C3F");
        this.m_CurrentTextColor = this.m_TextColor;
        this.m_CurrentBorderColor = this.m_BorderColor;

        stringFormat = new StringFormat()
        {
            Alignment = StringAlignment.Center,
            LineAlignment = StringAlignment.Center
        };
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);
        using (SolidBrush textBrush = new SolidBrush(this.m_CurrentTextColor))
        using (Pen pen = new Pen(this.m_CurrentBorderColor, this.BorderThickness))
        {
            e.Graphics.DrawRectangle(pen, e.ClipRectangle);
            e.Graphics.DrawString(this.Text, this.Font, textBrush, e.ClipRectangle, stringFormat);
        }
    }

    protected override void OnMouseDown(MouseEventArgs e)
    {
        base.OnMouseDown(e);
        this.m_CurrentTextColor = this.m_ActiveTextColor;
        this.Invalidate();
    }

    protected override void OnMouseUp(MouseEventArgs e)
    {
        base.OnMouseUp(e);
        this.m_CurrentTextColor = this.m_TextColor;
        this.Invalidate();
    }

    protected override void OnEnter(EventArgs e)
    {
        base.OnEnter(e);
        this.m_CurrentBorderColor = this.m_ActiveBorderColor;
        this.m_CurrentTextColor = this.m_ActiveTextColor;
        this.Invalidate();
    }

    protected override void OnLeave(EventArgs e)
    {
        base.OnLeave(e);
        this.m_CurrentBorderColor = this.m_TextColor;
        this.m_CurrentTextColor = this.m_BorderColor;
        this.Invalidate();
    }
}