Winform - 判断鼠标是否已离开用户控件

4
我遇到了一些问题,我认为应该(相对)容易解决。我有一个窗体和位于窗体底部的流动网格布局面板。在这个窗体里,我动态地添加了X个用户控件。这些控件都是相同类型的。
我的目标是,当用户将鼠标悬停在用户控件上时,它会打开另一个窗体,并将其定位在鼠标位置。当鼠标离开窗体时,打开的窗体消失。
这几乎完美地实现了。问题是,当用户控件内有像标签或文本框之类的任何东西时,它被视为已经离开了用户控件,所以窗体消失了。
我的想法是使用X和Y来确定它是否在UC内部,但我无法弄清楚如何做到这一点。
可以问一下:
1)最好的方法是什么? 2)如何编码,因为UC是动态的,我无法确定它们的确切位置。
谢谢
编辑
我正在尝试找出鼠标指针的位置,但还没有成功。下面的代码在UC SmallTagBox_MouseLeave事件中:
        Point loc = this.Location;
        Point p = this.PointToScreen(this.Location);
        Point p2 = this.PointToScreen(this.Parent.Location);

        Point ms = MousePosition;
        Rectangle screenBounds = new Rectangle(this.PointToScreen(this.Location), this.Size);
        if (!screenBounds.Contains(ms))
        {
            thw.Close();
            thw = null;
        }
  • loc {X = 275 Y = 3} System.Drawing.Point
  • p {X = 808 Y = 908} System.Drawing.Point
  • p {X = 808 Y = 908} System.Drawing.Point
  • p2 {X = 545 Y = 1542} System.Drawing.Point
  • ms {X = 574 Y = 914} System.Drawing.Point
  • screenBounds {X = 808 Y = 908 Width = 62 Height = 29} System.Drawing.Rectangle

我不明白为什么相对于屏幕,p2(其父元素)的Y值可以更大。

4个回答

4

挂钩所有控件的MouseEnter和MouseLeave事件,然后判断它是否仍在窗体内是相当麻烦的。一个简单的定时器也可以完成这项工作:

  public partial class Form1 : Form {
    private Timer mTimer;
    public Form1() {
      InitializeComponent();
      mTimer = new Timer();
      mTimer.Interval = 200;
      mTimer.Tick += mTimer_Tick;
      mTimer.Enabled = true;
    }
    private void mTimer_Tick(object sender, EventArgs e) {
      if (!this.DesktopBounds.Contains(Cursor.Position)) this.Close();
    }
  }

嗨nobugz,如果鼠标在弹出的表单内部,那么我认为这将起作用,但是鼠标引用在用户控件上。该表单靠近它但不在其上方,因此鼠标不会进入该表单。因此,我不认为我可以使用DesktopBounds。 - Jon
我做出了妥协,将计时器放在弹出窗体上,并让它在X秒后消失,即使鼠标仍然存在。 - Jon
谢谢!在我的情况下运行得非常好! - Tim Friesen

0

想法1)当MouseLeave事件触发时,您可以检查鼠标坐标(相对于屏幕),并检查它们是否仍在用户控件的边界内。如果是,则应假定鼠标必须通过控件返回以离开边界,并且这次可以安全地忽略事件。

想法2)将MouseEnter事件处理程序附加到子控件。然后,当鼠标进入其中一个时,您将知道并可以忽略用户控件的MouseLeave事件。然后,当子项的MouseLeave事件触发时,请再次检查用户控件的MouseEnter


我尝试过这个,但失败得很惨。我相信这是可能的,但我无法让我的边界起作用。如果有人能提供一些示例,那就太好了! - Jon

0

我认为你应该为每个控件添加一个MouseLeave事件处理程序,并使用Parent属性来找到你想要的用户控件。我同意,这可能会有点痛苦。


0

您还可以循环遍历您控件上的所有子控件(递归),并对它们附加MouseEnter和MouseLeave事件。

如果鼠标在您的控件或某个子控件内,您需要进行一些记录。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接