I have a button. On Button.MouseRightButtonDown, I'm calling Mouse.Capture(button), because I want to detect if someone releases right-click outside of the Button.
I also have a Button.MouseLeave event registered. If someone right-click-drags the mouse off the button, I want this event to trigger.
Unfortunately, it seems like Mouse.Capture somehow blocks MouseLeave from occuring.
Does anyone know a workaround, or maybe can point out where I'm going wrong?
(By the way, if anyone's curious what I'm doing this for, see my other question.)
When mouse is captured, you can use MouseMove and hit-testing to determine whether the mouse within your element or another.
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
if (this.IsMouseCaptured)
{
HitTestResult ht = VisualTreeHelper.HitTest(this, e.GetPosition(this));
if (ht != null)
{
DependencyObject current = ht.VisualHit;
while (current != this && current != null)
{
current = VisualTreeHelper.GetParent(current);
}
if (current == this)
{
Debug.WriteLine("Inside");
return;
}
}
Debug.WriteLine("Outside");
}
}
The following code can be used to avoid tree walk:
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
if (this.IsMouseCaptured)
{
bool isInside = false;
VisualTreeHelper.HitTest(
this,
d =>
{
if (d == this)
{
isInside = true;
}
return HitTestFilterBehavior.Stop;
},
ht => HitTestResultBehavior.Stop,
new PointHitTestParameters(e.GetPosition(this)));
if (isInside)
{
Debug.WriteLine("Inside");
}
else
{
Debug.WriteLine("Outside");
}
}
}
Following on from my answer to your related question, if you use CaptureMouse()
from UIElement
in place of Mouse.Capture(...) then you will see the correct behaviour.
public class MyButton : Button
{
protected override void OnMouseRightButtonDown(MouseButtonEventArgs e)
{
base.OnMouseRightButtonDown(e);
CaptureMouse();
}
protected override void OnMouseRightButtonUp(MouseButtonEventArgs e)
{
base.OnMouseRightButtonUp(e);
ReleaseMouseCapture();
}
protected override void OnMouseEnter(MouseEventArgs e)
{
base.OnMouseEnter(e);
Debug.WriteLine("Mouse enter");
}
protected override void OnMouseLeave(MouseEventArgs e)
{
base.OnMouseLeave(e);
Debug.WriteLine("Mouse leave");
}
}