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
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.
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
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
'Mouse is inside the form
Else
'Mouse is outside of form
End If
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;
}
}
You should listen:
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");
}