Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF Mousedown => No MouseLeave Event

Tags:

events

wpf

mouse

I'm building a Windows Presentation Foundation control with Microsoft Blend.

When I leave my control by pressing the left-mouse-button, the MouseLeave-Event is not raised. Why not?

like image 869
freakinpenguin Avatar asked Sep 26 '10 12:09

freakinpenguin


3 Answers

This is intended behaviour: When you are doing mousedown on a control and leaving the control, the control STILL retains its "capture" on the mouse, meaning the control won't fire the MouseLeave-Event. The Mouse-Leave Event instead will be fired, once the Mousebutton is released outside of the control.

To avoid this, you can simple tell your control NOT to capture the mouse at all:

private void ControlMouseDown(System.Object sender, System.Windows.Forms.MouseEventArgs e)
{
    Control control = (Control) sender;
    control.Capture = false; //release capture.
}

Now the MouseLeave Event will be fired even when moving out while a button is pressed.

If you need the Capture INSIDE the Control, you need to put in more effort:

  • Start tracking the mouseposition manually, when the mousekey is pressed

  • Compare the position with the Top, Left and Size Attributes of the control in question.

  • Decide whether you need to stop the control capturing your mouse or not.

    public partial class Form1 : Form
    {
    private Point point;
    private Boolean myCapture = false;
    
    public Form1()
    {
        InitializeComponent();
    }
    
    private void button1_MouseDown(object sender, MouseEventArgs e)
    {
        myCapture = true;
    }
    
    private void button1_MouseMove(object sender, MouseEventArgs e)
    {
        if (myCapture)
        {
            point = Cursor.Position;
    
            if (!(point.X > button1.Left && point.X < button1.Left + button1.Size.Width && point.Y > button1.Top && point.Y < button1.Top + button1.Size.Height))
            {
                button1.Capture = false; //this will release the capture and trigger the MouseLeave event immediately.
                myCapture = false;
            }
        }
    }
    
    private void button1_MouseLeave(object sender, EventArgs e)
    {
        MessageBox.Show("Mouse leaving");
    }
    

    }

of course you need to stop the own tracking ( myCapture=false;) on MouseUp. Forgot that one :)

like image 94
dognose Avatar answered Nov 24 '22 10:11

dognose


When I don't get mouse events I expect I typically use Snoop to help me understand what is happening.

Here are a couple of links:

1- Snoop (a WPF utility)
2- CodePlex project for Snoop

like image 26
Zamboni Avatar answered Nov 24 '22 08:11

Zamboni


And for completeness and historical reasons (not the bounty - it doesn't make sense having two duplicate questions - you should probably move it into one if not too late)...

I made a thorough solution using global mouse hook here (approach 2)
WPF: mouse leave event doesn't trigger with mouse down

And simplified its use - you can use it by binding to commands in your view-model - e.g.

my:Hooks.EnterCommand="{Binding EnterCommand}"
my:Hooks.LeaveCommand="{Binding LeaveCommand}"
my:Hooks.MouseMoveCommand="{Binding MoveCommand}"

...more details in there

like image 25
NSGaga-mostly-inactive Avatar answered Nov 24 '22 10:11

NSGaga-mostly-inactive