2011-04-27 35 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