繁体   English   中英

如何有效地绘制控制边界

[英]How to draw control border in efficent way

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

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

只有当鼠标悬停在控件上时,您才应该使控件无效。 您可以通过检查可用于所有控件的 static MousePosition变量来检查鼠标的 position。 只需添加一个检查以有条件地使您的控件无效。

最简单的方法是在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);
}

要以更稳健的方式处理此问题,您需要确定鼠标是否实际进入或离开您的控件。 您需要保留两个变量来保留 state,一个用于判断鼠标当前是否在您的控件上,另一个用于判断鼠标是否在您的控件上(自上次检查以来)。 如果这些不同,则使您的控制无效。 您将获得额外的好处,即知道鼠标是否在您的控件上,这样您就可以有条件地在您的绘制方法中执行一些操作。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM