如何有效地绘制控制边界

本文关键字:控制 边界 绘制 有效地 | 更新日期: 2023-09-27 17:53:11

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

有没有更好的方法可以找到一个合适的时机来重新绘制控件,然后对mouseLeave和mouseEnter做出反应??

如何有效地绘制控制边界

只有当鼠标位于控件上方时,才应使控件无效。您可以通过检查所有控件都可用的静态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();