Windows表单上的鼠标离开事件

5

我已经在Windows表单上设置了“鼠标离开”事件,并且当鼠标离开可见区域时,我想隐藏该表单。

但这就是我面临问题的地方。即使我将鼠标移动到同一表单上的按钮上,它也会调用“鼠标离开”事件,这会使该表单不可见。

这意味着我必须防止在将鼠标移动到按钮时触发该事件。但如何做到呢? 还有其他方法吗?


1
表单上的鼠标事件问题在于,如果您有任何控件覆盖整个表单客户区域(例如停靠),则它们中的任何一个都不会触发。因此,如果您像MusiGenesis建议的那样使用MouseMove事件,请注意这一点。 - Igby Largeman
2
没有简单的方法来完成这个任务,你需要使用一个计时器。当 this.Bounds.Contains(Cursor.Position) 为 false 时,隐藏窗体。让窗体再次显示将会非常困难 :) - Hans Passant
3个回答

1

没有简单的方法来做到这一点。一种方法可能是检查表单内的所有控件,如果鼠标不在任何一个控件上,这意味着鼠标在表单外面。

另一种方法可能是在鼠标离开事件中检查鼠标是否在窗口边界内部。


这需要太多的努力,不是吗? - Muhammad Ali Dildar
是的,正如我所说,没有简单的方法来做到这一点。如果您在表单内有少量控件,则可以使用第一种选项,否则请选择第二种选项。 - Haris Hasan
您可以通过Controls属性(http://msdn.microsoft.com/en-us/library/system.windows.forms.control.controls.aspx)访问所有控件和子控件。如果窗体不太大/复杂,您可以在每个MouseLeave事件中遍历此控件树。 - bitbonk
@HarisHasan 下面是一个更好的解决方案,Hassan(还记得我吗?:))https://dev59.com/D0bRa4cB1Zd3GeqPxy1c - PUG

0

这非常简单...只需添加这个:

protected override void OnMouseLeave(EventArgs e)
{

    if(this.ClientRectangle.Contains(this.PointToClient(Control.MousePosition)))
         return;
    else
    {
        base.OnMouseLeave(e);
    }
}

0
// On the form's MouseLeave event, please checking for mouse position is not in each control's client area.
private void TheForm_MouseLeave(object sender, EventArgs e)
{
    bool mouse_on_control = false;
    foreach (var c in Controls)
        mouse_on_control |= c.RectangleToScreen(c.ClientRectangle).Contains(Cursor.Position);
    if (!mouse_on_control)
        Close();
}

// And in addition, if any control inside has its client area overlapping the form's client area at any border, 
// please also checking if mouse position is outside the form's client area on the control's MouseLeave event.
private void ControlOverlappedTheFormsBorder_MouseLeave(object sender, EventArgs e)
{
    if (!RectangleToScreen(ClientRectangle).Contains(Cursor.Position))
        Close();
}

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