我有一个包含很多控件的表单,我该如何检测鼠标离开表单的事件?我尝试为每个控件和表单都绑定MouseLeave事件,但这并不起作用,因为当鼠标经过控件时,这些事件会一直触发。有没有一种真正有效的方法?
我有一个包含很多控件的表单,我该如何检测鼠标离开表单的事件?我尝试为每个控件和表单都绑定MouseLeave事件,但这并不起作用,因为当鼠标经过控件时,这些事件会一直触发。有没有一种真正有效的方法?
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;
}
}
请注意:
只需将您的监听器链接到一个函数,该函数检查光标是否在表单客户端区域内。
尝试以下代码:
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 编写了这个版本,递归添加 MouseLeaveHandlers 到窗体上的所有控件,然后使用漂亮的 Clientrectangle.Contains(pt) 来检查鼠标光标是否在窗体内或外。效果非常好。感谢 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
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
'Mouse is inside the form
Else
'Mouse is outside of form
End If