当Mouse.Capture()处于活动状态时,我可以获得MouseLeave事件吗?

时间:2012-04-01 01:00:10

标签: c# wpf mouse capture mouseleave

我有一个按钮。在Button.MouseRightButtonDown上,我正在调用Mouse.Capture(按钮),因为我想检测是否有人在Button外部右键单击。

我还注册了一个Button.MouseLeave事件。如果有人右键单击 - 将鼠标拖离按钮,我希望触发此事件。

不幸的是,似乎Mouse.Capture以某种方式阻止了MouseLeave的发生。

有没有人知道解决方法,或者可能指出我哪里出错了?

(顺便说一下,如果有人好奇我正在做的事情,请参阅my other question。)

2 个答案:

答案 0 :(得分:4)

捕获鼠标时,您可以使用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");
        }
    }
}

答案 1 :(得分:0)

根据我对相关问题的回答,如果您使用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");
    }
}