问题
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.)
回答1:
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");
}
}
}
回答2:
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");
}
}
来源:https://stackoverflow.com/questions/9961050/can-i-get-a-mouseleave-event-while-mouse-capture-is-active