如何在WPF中取消关联触摸和鼠标事件

本文关键字:触摸 鼠标 事件 关联 取消 WPF | 更新日期: 2023-09-27 18:21:37

我正在构建一个必须支持触摸操作的WPF应用程序。在这种情况下,它是"点击"事件。我创建了一个类来将单击行为添加到FrameworkElement中。问题是,当我触摸屏幕(TouchDown),然后移动一点(大约10像素)或快速点击时,MouseLeftButtonDown事件也会触发。。我还没有找到问题的根源,所以我在这里寻求帮助。如果你有任何问题,不要犹豫。提前谢谢。

public class ClickBehavior : Behavior
{
    private const double MAXIMUM_DELTA_CHANGED = 10.0;
    public const int MAXIMUM_TOUCH_DURATION = 1000;
    private bool pressed = false;
    private Position initialPosition;
    private DateTime startDate;
    public ClickBehavior(FrameworkElement _fe)
        : base(_fe)
    {
        fe.MouseLeftButtonDown += OnMouseLeftButtonDown;
        fe.TouchDown           += OnTouchDown;
    }

    public static readonly RoutedEvent ClickEvent = EventManager.RegisterRoutedEvent(
"Click", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(FrameworkElement));

    private void RaiseClickEvent()
    {
        RoutedEventArgs newEventArgs = new RoutedEventArgs(ClickEvent);
        fe.RaiseEvent(newEventArgs);
    }

    #region touchHandle
    private void StopTouchManipulation()
    {
        pressed = false;
        initialPosition = null;          
        fe.TouchUp      -= OnTouchUp;
        fe.TouchLeave   -= OnTouchLeave;
        fe.TouchEnter   -= OnTouchEnter;
        fe.TouchMove    -= OnTouchMove;
    }
    private void OnTouchDown(object sender, TouchEventArgs e)
    {
        DebugManager.Debug("Touch Down");
        e.Handled = true;
        pressed = true;
        initialPosition = new Position(Mouse.GetPosition(fe));
        startDate = DateTime.Now;
        fe.TouchUp      += OnTouchUp;
        fe.TouchLeave   += OnTouchLeave;
        fe.TouchEnter   += OnTouchEnter;
        fe.TouchMove    += OnTouchMove;          
    }
    private void OnTouchUp(object sender, TouchEventArgs e)
    {
        e.Handled = true;
        if ((DateTime.Now - startDate).TotalMilliseconds < MAXIMUM_TOUCH_DURATION)
        {
            if (pressed)
            {
                RaiseClickEvent();
            }
        }
        StopTouchManipulation();
    }
    private void OnTouchLeave(object sender, TouchEventArgs e)
    {
        e.Handled = true;
        StopTouchManipulation();
    }
    private void OnTouchEnter(object sender, TouchEventArgs e)
    {
        e.Handled = true;
        StopTouchManipulation();
    }
    private void OnTouchMove(object sender, TouchEventArgs e)
    {
        e.Handled = true;
        if (pressed)
        {
            Position pos = new Position(Mouse.GetPosition(fe));
            double distance = Position.GetDistance(initialPosition, pos);
            if (distance >= MAXIMUM_DELTA_CHANGED)
            {
                StopTouchManipulation();         
            }
        }
    }

    #endregion

    #region mouseHandle
    private void StopClickManipulation()
    {
        pressed = false;
        initialPosition = null;
        fe.MouseLeftButtonUp -= OnMouseLeftButtonUp;
        fe.MouseEnter        -= OnMouseEnter;
        fe.MouseLeave        -= OnMouseLeave;
        fe.MouseMove         -= OnMouseMove;
    }
    private void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        DebugManager.Debug("Mouse Left Down");
        e.Handled = true;
        pressed = true;
        initialPosition = new Position(Mouse.GetPosition(fe));
        fe.MouseLeftButtonUp += OnMouseLeftButtonUp;
        fe.MouseEnter        += OnMouseEnter;
        fe.MouseLeave        += OnMouseLeave;
        fe.MouseMove         += OnMouseMove;
    }
    private void OnMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    {
        e.Handled = true;
        if (pressed)
        { 
            RaiseClickEvent();
        }
        StopClickManipulation();
    }
    private void OnMouseEnter(object sender, MouseEventArgs e)
    {
        e.Handled = true;
        StopClickManipulation();
    }
    private void OnMouseLeave(object sender, MouseEventArgs e)
    {
        e.Handled = true;
        StopClickManipulation();
    }
    private void OnMouseMove(object sender, MouseEventArgs e)
    {
        e.Handled = true;
        if (pressed)
        {   
            Position pos = new Position(Mouse.GetPosition(fe));
            double distance = Position.GetDistance(initialPosition, pos);
            if ( distance>= MAXIMUM_DELTA_CHANGED)
            {
                StopClickManipulation();   
            }
        }
    }
    #endregion
}

如何在WPF中取消关联触摸和鼠标事件

fe.IsManipulationEnable = true;

在构造函数中已经完成了技巧:

public class Behavior<T> where T : FrameworkElement
{
    public static bool IsManipulating = false;
    protected T fe;
    private bool enable;
    public bool Enable
    {
        get
        {
            return enable;
        }
        set
        {
            bool changed = false;
            if (enable != value)
            {
                changed = true;
            }
            enable = value;
            if (changed)
            {
                if (enable)
                {
                    Enable_Partial();
                }
                else
                {
                    Disable_Partial();
                }
            }
        }
    }

    public Behavior(T _fe)
    {
        fe = _fe;
        fe.IsManipulationEnabled = true;
        enable = true;
    }
    protected virtual void Enable_Partial()
    {
    }
    protected virtual void Disable_Partial()
    {
    }
}

public class ClickBehavior : Behavior<FrameworkElement>
{
    public const double MAXIMUM_TOUCH_DELTA_CHANGED = 5;
    public const double MAXIMUM_MOUSE_DELTA_CHANGED = 10;
    public const int MAXIMUM_TOUCH_DURATION = 333;
    private Position initialPosition;
    private DateTime startDate;
    public ClickBehavior(FrameworkElement _fe)
        : base(_fe)
    {
        fe.MouseLeftButtonDown += OnMouseLeftButtonDown;
        fe.TouchDown += OnTouchDown;
    }

    public static readonly RoutedEvent ClickEvent = EventManager.RegisterRoutedEvent(
"Click", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(FrameworkElement));

    // This method raises the Tap event
    private void RaiseClickEvent()
    {
        RoutedEventArgs newEventArgs = new RoutedEventArgs(ClickEvent);
        fe.RaiseEvent(newEventArgs);
    }

    #region touch handle
    private void StopTouchManipulation(TouchEventArgs e)
    {

        initialPosition = null;
        fe.TouchUp -= OnTouchUp;
        fe.TouchLeave -= OnTouchLeave;
        MainWindow.Current.TouchMove -= OnTouchMove;

    }
    private void OnTouchDown(object sender, TouchEventArgs e)
    {
        if (Enable)
        {
            initialPosition = new Position(e.GetTouchPoint(MainWindow.Current));
            startDate = DateTime.Now;
            fe.TouchUp += OnTouchUp;
            fe.TouchLeave += OnTouchLeave;
            MainWindow.Current.TouchMove += OnTouchMove;
        }

    }
    private void OnTouchUp(object sender, TouchEventArgs e)
    {
        TouchPoint tp = e.GetTouchPoint(fe);
        Rect bounds = new Rect(new Point(0, 0), fe.RenderSize);
        if (bounds.Contains(tp.Position))
        {
            if ((DateTime.Now - startDate).TotalMilliseconds < MAXIMUM_TOUCH_DURATION)
            {
                e.Handled = true;
                RaiseClickEvent();
            }
        }

        StopTouchManipulation(e);
    }
    private void OnTouchLeave(object sender, TouchEventArgs e)
    {
        StopTouchManipulation(e);
    }
    private void OnTouchMove(object sender, TouchEventArgs e)
    {
        Position pos = new Position(e.GetTouchPoint(MainWindow.Current));
        double distance = Position.GetDistance(initialPosition, pos);
        if (distance >= MAXIMUM_TOUCH_DELTA_CHANGED)
        {
            StopTouchManipulation(e);
        }
    }

    #endregion

    #region mouse handle
    private void StopClickManipulation()
    {
        initialPosition = null;
        fe.MouseLeftButtonUp -= OnMouseLeftButtonUp;
        fe.MouseLeave -= OnMouseLeave;
        MainWindow.Current.MouseMove -= OnMouseMove;
    }
    private void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        if (Enable)
        {
            initialPosition = new Position(Mouse.GetPosition(MainWindow.Current));
            fe.MouseLeftButtonUp += OnMouseLeftButtonUp;
            fe.MouseLeave += OnMouseLeave;
            MainWindow.Current.MouseMove += OnMouseMove;
        }

    }
    private void OnMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    {
        e.Handled = true;
        RaiseClickEvent();
        StopClickManipulation();
    }
    private void OnMouseEnter(object sender, MouseEventArgs e)
    {
        StopClickManipulation();
    }
    private void OnMouseLeave(object sender, MouseEventArgs e)
    {
        StopClickManipulation();
    }
    private void OnMouseMove(object sender, MouseEventArgs e)
    {
        Position pos = new Position(Mouse.GetPosition(MainWindow.Current));
        double distance = Position.GetDistance(initialPosition, pos);
        if (distance >= MAXIMUM_MOUSE_DELTA_CHANGED)
        {
            StopClickManipulation();
        }
    }
    #endregion
}