2011-04-27 76 views
0

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

有没有更好的方法来找到适当的时刻来重绘控制,然后在mouseLeave和mouseEnter上作出反应?

回答

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

所以我应该使用mouseOver事件?但是,如果/当鼠标离开我的控制(绘制默认边框)时,我将如何识别? – tron 2011-04-27 19:31:53

+0

“只有鼠标悬停时,您才应该使控件失效。”这在我这里没有意义。不应该只在鼠标悬停状态发生变化时(in - > out或out - > in)失效? – Justin 2011-04-27 19:34:11

+0

@tron:对不起,我不知道该怎么处理。 ;)我会更新我的答案,包括这一点。 – 2011-04-27 19:35:43