Can I get a MouseLeave event while Mouse.Capture() is active?

我们两清 提交于 2019-12-13 02:57:14

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!