如何检测鼠标何时离开表格?

时间:2021-10-25 07:18:21

I have a form with a lot of controls on it. How can I detect when the mouse leaves the form? I've tried wiring up a MouseLeave event for every single control and the form, but that does not work because those events fire all the time as the mouse passes over controls. Is there a way that actually works.?

我有一个表格,上面有很多控件。如何检测鼠标何时离开表格?我已尝试为每个控件和表单连接一个MouseLeave事件,但这不起作用,因为当鼠标经过控件时,这些事件会一直触发。有没有一种实际有效的方法。

4 个解决方案

#1


5  

You should listen:

你应该听:

  • MouseLeave events of all controls of the form
  • MouseLeave窗体的所有控件的事件

  • MouseLeave event of the form
  • 表单的MouseLeave事件

Just link your listeners to a function that checks whether the cursor is in the forms client are or not.

只需将您的侦听器链接到一个函数,该函数检查光标是否在表单客户端中。

Try this:

    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


4  

The only reliable way I know of is a timer. Here's sample code that tweaks the opacity on a roll-over:

我所知道的唯一可靠的方法是计时器。这是调整翻转时不透明度的示例代码:

  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;
    }
  }

#3


2  

From looking at aygunes.myopenid.com's answer I made this version in Vb.Net that recursive adding MouseLeaveHandlers to all controls on the form and then Use the nice Clientrectangle.Contains(pt) to check if mousecursor is on or out of form. Working like a charm. Cred goes to aygunes.myopenid.com.

从查看aygunes.myopenid.com的回答我在Vb.Net中创建了这个版本,它将MouseLeaveHandlers递归添加到窗体上的所有控件,然后使用漂亮的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


1  

Put this in timer:

If PointToClient(MousePosition).X < Me.Size.Width AndAlso PointToClient(MousePosition).X > -1 AndAlso PointToClient(MousePosition).Y < Me.Size.Height AndAlso PointToClient(MousePosition).Y > -1 Then

如果PointToClient(MousePosition).X -1 AndAlso PointToClient(MousePosition).Y -1 Then

'Mouse is inside the form

'鼠标在表格内

Else

'Mouse is outside of form

'鼠标不在形式之内

End If

- By SNK

#1


5  

You should listen:

你应该听:

  • MouseLeave events of all controls of the form
  • MouseLeave窗体的所有控件的事件

  • MouseLeave event of the form
  • 表单的MouseLeave事件

Just link your listeners to a function that checks whether the cursor is in the forms client are or not.

只需将您的侦听器链接到一个函数,该函数检查光标是否在表单客户端中。

Try this:

    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


4  

The only reliable way I know of is a timer. Here's sample code that tweaks the opacity on a roll-over:

我所知道的唯一可靠的方法是计时器。这是调整翻转时不透明度的示例代码:

  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;
    }
  }

#3


2  

From looking at aygunes.myopenid.com's answer I made this version in Vb.Net that recursive adding MouseLeaveHandlers to all controls on the form and then Use the nice Clientrectangle.Contains(pt) to check if mousecursor is on or out of form. Working like a charm. Cred goes to aygunes.myopenid.com.

从查看aygunes.myopenid.com的回答我在Vb.Net中创建了这个版本,它将MouseLeaveHandlers递归添加到窗体上的所有控件,然后使用漂亮的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


1  

Put this in timer:

If PointToClient(MousePosition).X < Me.Size.Width AndAlso PointToClient(MousePosition).X > -1 AndAlso PointToClient(MousePosition).Y < Me.Size.Height AndAlso PointToClient(MousePosition).Y > -1 Then

如果PointToClient(MousePosition).X -1 AndAlso PointToClient(MousePosition).Y -1 Then

'Mouse is inside the form

'鼠标在表格内

Else

'Mouse is outside of form

'鼠标不在形式之内

End If

- By SNK