如何在WPF中分离触摸和鼠标事件

时间:2015-11-12 16:19:36

标签: c# wpf touch

我正在构建一个必须支持触摸操作的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
}

1 个答案:

答案 0 :(得分:0)

该行

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
}