如何以有效的方式绘制控制边框

时间:2011-04-27 18:26:07

标签: c# winforms paint

您好 我有我的自定义控件,我通过重写OnPaint方法绘制颜色边框。但是,如果鼠标进入控制区域并且鼠标离开控件,我想更改控件的边框颜色。起初我想对事件mouseLeave和mouseEnter做出反应并用适当的颜色重新绘制控件边框。然而,在我的控制下是几个文本框,标签等 - 所以事件mouseEnter和mouseLeave激发了很多次,这导致我的控件闪烁(因为许多重绘)。

有没有更好的方法找到适当的时刻来重绘控件然后对mouseLeave和mouseEnter做出反应?

1 个答案:

答案 0 :(得分:2)

只有当鼠标悬停在控件上时,才会使控件无效。您可以通过检查可用于所有控件的静态MousePosition变量来检查鼠标的位置。只需添加一项检查即可有条件地使您的控件无效。

执行此操作的最简单方法是在MouseEnterMouseLeave事件中执行这些检查,然后进行相应的无效处理。

protected override void OnMouseEnter(EventArgs e)
{
    var mousePos = this.PointToClient(MousePosition);
    if (this.ClientRectangle.Contains(mousePos))
    {
        this.Invalidate(invalidateChildren: true);
    }
    base.OnMouseEnter(e);
}

protected override void OnMouseLeave(EventArgs e)
{
    var mousePos = this.PointToClient(MousePosition);
    if (!this.ClientRectangle.Contains(mousePos))
    {
        this.Invalidate(invalidateChildren: true);
    }
    base.OnMouseLeave(e);
}

要获得更强大的处理方法,您需要确定鼠标是否实际进入或离开您的控件。您需要保留两个变量以保持状态,一个用于判断鼠标当前是否在您的控件上,另一个用于判断鼠标是否在您的控件上(自上次检查后)。如果这些不同,则使控件无效。你会得到额外的好处,知道鼠标是否超过你的控制,所以你可以有条件地在你的绘画方法中执行一些操作。

private bool wasMouseOver;
private bool isMouseOver;
public bool IsMouseOver { get { return isMouseOver; } }
private void CheckMousePosition()
{
    var mousePos = this.PointToClient(MousePosition);
    wasMouseOver = isMouseOver;
    isMouseOver = this.ClientRectangle.Contains(mousePos);
    if (isMouseOver != wasMouseOver)
        this.Invalidate(invalidateChildren: true);
}

// then register this method to the mouse events
EventHandler mouseHandler = (sender, e) => CheckMousePosition();
MouseEnter += mouseHandler;
MouseLeave += mouseHandler;
MouseMove += (sender, e) => CheckMousePosition();