2008-11-10 97 views
3

我有一個窗體上有很多控件。如何檢測鼠標何時離開表單?我已經嘗試爲每個控件和窗體連接一個MouseLeave事件,但這不起作用,因爲這些事件隨着鼠標移過控件一直觸發。有沒有一種方法可以實際運作?如何檢測鼠標何時離開窗體?

+0

是的,它可以工作,但在運行使應用程序inaccesible到那些身體disablilties的風險。 http://www.w3.org/TR/2008/WD-UNDERSTANDING-WCAG20-20081103/keyboard-operation-keyboard-operable.html – StingyJack 2008-11-11 20:18:47

+0

您需要偵聽表單本身的mouseleave事件。 – korona 2008-11-10 22:55:47

+0

Korona,您的方法不起作用,因爲如果鼠標通過控件覆蓋的空間離開窗體,form_mouseLeave不會觸發。 – AngryHacker 2008-11-10 23:00:53

回答

5

你應該聽:

  • 形式的所有控件的鼠標離開事件
  • 形式的
  • 鼠標離開事件

聽衆只是鏈接到,檢查光標是否在一個函數表單客戶端是否。

試試這個:

protected override void OnControlAdded(ControlEventArgs e) 
    { 
     SubscribeEvents(e.Control); 
     base.OnControlAdded(e); 
    } 

    protected override void OnControlRemoved(ControlEventArgs e) 
    { 
     UnsubscribeEvents(e.Control); 
     base.OnControlRemoved(e); 
    } 

    private void SubscribeEvents(Control control) 
    { 
     control.MouseLeave += new EventHandler(control_MouseLeave); 
     control.ControlAdded += new ControlEventHandler(control_ControlAdded); 
     control.ControlRemoved += new ControlEventHandler(control_ControlRemoved); 

     foreach (Control innerControl in control.Controls) 
     { 
      SubscribeEvents(innerControl); 
     } 
    } 

    private void UnsubscribeEvents(Control control) 
    { 
     control.MouseLeave -= new EventHandler(control_MouseLeave); 
     control.ControlAdded -= new ControlEventHandler(control_ControlAdded); 
     control.ControlRemoved -= new ControlEventHandler(control_ControlRemoved); 

     foreach (Control innerControl in control.Controls) 
     { 
      UnsubscribeEvents(innerControl); 
     } 
    } 

    private void control_ControlAdded(object sender, ControlEventArgs e) 
    { 
     SubscribeEvents(e.Control); 
    } 

    private void control_ControlRemoved(object sender, ControlEventArgs e) 
    { 
     UnsubscribeEvents(e.Control); 
    } 

    protected override void OnMouseLeave(EventArgs e) 
    { 
     CheckMouseLeave(); 
     base.OnMouseLeave(e); 
    } 

    private void control_MouseLeave(object sender, EventArgs e) 
    { 
     CheckMouseLeave(); 
    } 

    private void CheckMouseLeave() 
    { 
     Point pt = PointToClient(Cursor.Position); 

     if (ClientRectangle.Contains(pt) == false) 
     { 
      OnMouseLeftFrom(); 
     } 
    } 

    private void OnMouseLeftFrom() 
    { 
     Console.WriteLine("Mouse left the form"); 
    } 
2

通過觀察aygunes.myopenid.com的答案,我在做Vb.Net這個版本遞歸添加表格上MouseLeaveHandlers所有控件,然後使用nice Clientrectangle.Contains( pt)來檢查mousecursor是否在窗體上。像魅力一樣工作。 Cred轉到aygunes.myopenid.com。

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 
    AddMouseLeaveHandlers() 
End Sub 
Sub AddMouseLeaveHandlers() 
    For Each c As Control In Me.Controls 
     HookItUp(c) 
    Next 
    AddHandler Me.MouseLeave, AddressOf CheckMouseLeave 
End Sub 
Sub HookItUp(ByVal c As Control)   
    AddHandler c.MouseLeave, AddressOf CheckMouseLeave 
    If c.HasChildren Then 
     For Each f As Control In c.Controls 
      HookItUp(f) 
     Next 
    End If 
End Sub 
Private Sub CheckMouseLeave(ByVal sender As Object, ByVal e As System.EventArgs) 
    Dim pt As Point = PointToClient(Cursor.Position) 
    If ClientRectangle.Contains(pt) = False Then 
     MsgBox("Mouse left form") 
    End If 
End Sub 
4

我知道的唯一可靠的方法是計時器。下面是示例代碼的調整上翻車的不透明度:

public partial class Form1 : Form { 
    Timer timer1 = new Timer(); 
    public Form1() { 
     InitializeComponent(); 
     this.Opacity = 0.10; 
     timer1.Tick += new EventHandler(timer1_Tick); 
     timer1.Interval = 200; 
     timer1.Enabled = true; 
    } 

    void timer1_Tick(object sender, EventArgs e) { 
     Point pos = Control.MousePosition; 
     bool inForm = pos.X >= Left && pos.Y >= Top && pos.X < Right && pos.Y < Bottom; 
     this.Opacity = inForm ? 0.99 : 0.10; 
    } 
    } 
1

定時器將這個:

如果PointToClient(MousePosition).X < Me.Size.Width AndAlso PointToClient(MousePosition)。 X> -1 AndAlso PointToClient(MousePosition).Y < Me.Size.Height AndAlso PointToClient(MousePosition).Y> -1然後

「鼠標是在表單內

否則

「鼠標形式

結束如果

以外 - 由SNK