Могу ли я получить событие MouseLeave, когда Mouse.Capture() активен?
У меня есть кнопка. На Button.MouseRightButtonDown я вызываю Mouse.Capture(button), потому что я хочу определить, отпускает ли кто-нибудь правый щелчок за пределами Button.
У меня также зарегистрировано событие Button.MouseLeave. Если кто-то щелкнет правой кнопкой мыши по кнопке, я хочу, чтобы это событие сработало.
К сожалению, кажется, что Mouse.Capture каким-то образом блокирует MouseLeave.
Кто-нибудь знает обходной путь, или, может быть, может указать, где я иду не так?
(Кстати, если кому-то интересно, зачем я это делаю, см. Мой другой вопрос.)
2 ответа
Когда мышь захвачена, вы можете использовать MouseMove и проверку нажатия, чтобы определить, находится ли мышь внутри вашего элемента или другого.
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");
}
}
Следующий код можно использовать, чтобы избежать обхода дерева:
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");
}
}
}
Исходя из моего ответа на ваш связанный вопрос, если вы используете CaptureMouse()
от UIElement
вместо Mouse.Capture(...) вы увидите правильное поведение.
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");
}
}