Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2008/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Winforms 如何检测鼠标何时离开窗体?_Winforms_Visual Studio 2008 - Fatal编程技术网

Winforms 如何检测鼠标何时离开窗体?

Winforms 如何检测鼠标何时离开窗体?,winforms,visual-studio-2008,Winforms,Visual Studio 2008,我有一个表单,上面有很多控件。如何检测鼠标何时离开窗体?我已经尝试为每个控件和窗体连接MouseLeave事件,但这不起作用,因为当鼠标经过控件时,这些事件会一直触发。有没有一种方法能真正起作用呢?你应该听听: 窗体的所有控件的MouseLeave事件 窗体的MouseLeave事件 只需将侦听器链接到一个函数,该函数用于检查光标是否位于客户端所在的窗体中 试试这个: protected override void OnControlAdded(ControlEventArgs e)

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

你应该听听:

  • 窗体的所有控件的MouseLeave事件
  • 窗体的MouseLeave事件
只需将侦听器链接到一个函数,该函数用于检查光标是否位于客户端所在的窗体中

试试这个:

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

通过查看aygunes.myopenid.com的答案,我在Vb.Net中制作了这个版本,递归地将MouseleAvehollers添加到表单上的所有控件中,然后使用漂亮的Clientrectangle.Contains(pt)检查MouseCursors是否在表单上。工作得很有魅力。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

我所知道的唯一可靠的方法就是定时器。下面是调整翻滚不透明度的示例代码:

  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:表单{
计时器计时器1=新计时器();
公共表格1(){
初始化组件();
不透明度=0.10;
timer1.Tick+=新事件处理程序(timer1\u Tick);
计时器1。间隔=200;
timer1.Enabled=true;
}
无效计时器1_刻度(对象发送方,事件参数e){
点位置=控制。鼠标位置;
bool inForm=位置X>=左侧和位置Y>=顶部和位置X<右侧和位置Y<底部;
不透明度=0.99:0.10;
}
}
将其放入计时器:

如果指向客户端(MousePosition).X-1并同时指向客户端(MousePosition).Y-1则
“鼠标在窗体内
其他的
“鼠标在外形之外
如果结束

Nice,我学到了一些新东西:ClientRectangle.Contains(pt)谢谢+1尽管这方面的“优雅”因素非常低,但我同意这可能是唯一可靠的方法。您需要为窗体本身收听mouseleave事件。Korona,您的方法不起作用,因为如果鼠标通过覆盖控件的空间离开窗体,form_mouseLeave不会启动。我把这个链接放在这里作为参考。这个链接展示了如何使用win32 API在.Net中添加鼠标和键盘事件的挂钩,这样即使你的应用程序没有焦点,你也可以接收事件:即使它没有回答这个问题,我认为在解决类似问题和其他类似的键盘/鼠标事件问题时,相关信息非常有用。仅此而已很好,但是如果有人使用触摸屏PC运行您的应用程序,而鼠标从未进入或离开任何东西,会发生什么呢?虽然我认为为eyecandy做这样的事情很好,但我强烈建议不要将其用于任何真正的应用程序功能,或者只能使用键盘(WCAG-)