在 WinRT 应用程序中处理两指、三指、四指滑动手势 [英] Handling Two, Three, Four Fingers Swipe Gestures in WinRT App

查看:18
本文介绍了在 WinRT 应用程序中处理两指、三指、四指滑动手势的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下代码:

private Point initialpoint;

private void ManipulationStarted(object sender, ManipulationStartedRoutedEventArgs e)
{
    initialpoint = e.Position;
}

private void ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
    Point currentpoint = e.Position;
    if (currentpoint.X - initialpoint.X >= 100)
    {
        System.Diagnostics.Debug.WriteLine("Swipe Right");
        e.Complete();
    }
}

我可以很容易地处理 1 个手指滑动手势,但我也想处理 2、3、4 个手指滑动手势.谁能告诉我该怎么做?

I can handle 1 finger swipe gesture very easily, but I want to handle 2, 3, 4 fingers swipe gestures also. Can anyone tell me how to do that?

推荐答案

据此MSDN 论坛发帖 您需要使用 指针 通知.工作示例代码的文档位于 MSDN 库<​​/a>

According to this MSDN Forum Posting you will need to use pointer notifications. The documentation with working example code resides in the MSDN Library

来自上一个链接:

指针对象表示来自输入设备(例如鼠标、笔/触控笔、单指或多指)的单个、唯一的输入触点"(PointerPoint).系统在首次检测到接触时创建一个指针,并在指针离开(离开)检测范围或取消时销毁它.在多个设备或多点触控输入的情况下,每个接触都被视为唯一的指针.

A pointer object represents a single, unique input "contact" (a PointerPoint) from an input device (such as a mouse, pen/stylus, single finger, or multiple fingers). The system creates a pointer when a contact is first detected and destroys it when the pointer leaves (departs) detection range or is canceled. In the case of multiple devices or multi-touch input, each contact is treated as a unique pointer.

<小时>

请注意,我没有多点触控 Windows 8 设备来测试此代码.因此,它已经在 Simuator 中进行了所有限制的测试,并且如上述链接中所述,Windows 8 没有内置手势支持来检测多个手指,您必须使用较低级别的功能.


Just a caveat, I do not have a multitouch Windows 8 device to test this code on. So it has been tested in the Simuator with all of its limitations, and as mentioned in the above links Windows 8 doesn't not have built in gesture support for detecting multiple fingers you have to use lower level functions.

首先,我在上面的 MSDN 示例代码中添加了两个字典,并为类定义的滑动阈值添加了两个变量.

First of all I added two more dictionary's to the above MSDN example code and two variable for your Swipe Threshold to the Class definitions.

Dictionary<uint, Point> startLocation;
Dictionary<uint, bool> pointSwiped;
int swipeThresholdX = 100;
int swipeThresholdY = 100;

然后我在表单的构造函数中初始化字典

I then initialize the Dictionarys in the Form's Constructor

startLocation = new Dictionary<uint, Point>((int)SupportedContacts.Contacts);
pointSwiped = new Dictionary<uint, bool>((int)SupportedContacts.Contacts);

然后,原始字典添加到或删除项目的每个地方我都对新字典做了同样的事情

Then every place that the Original Dictionary was added to or had an item removed I did the same with the new Dictionary's

添加:

startLocation[pt.PointerId] = pt.Position;
pointSwiped[pt.PointerId] = false;

删除:

startLocation.Remove(pt.PointerId);
pointSwiped.Remove(pt.PointerId);

然后最后把它们放在PointerMovedEvent中:

Then finally put them together in the PointerMovedEvent:

private void targetContainer_PointerMoved(object sender, PointerRoutedEventArgs e)
{
    Windows.UI.Input.PointerPoint currentPoint = e.GetCurrentPoint(targetContainer);
    if (currentPoint.IsInContact)
    {
        if (startLocation.ContainsKey(currentPoint.PointerId))
        {
            Point startPoint = startLocation[currentPoint.PointerId];
            if (Math.Abs(currentPoint.Position.X - startPoint.X) > swipeThresholdX) // I only did one Axis for testing
            {
                pointSwiped[currentPoint.PointerId] = true;
            }
        }
    }
    updateInfoPop(e);
}               

最终修改的 MSDN 示例:

Final Modified MSDN Example:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238

namespace PointerInput
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class MainPage : Page
    {
        Windows.Devices.Input.TouchCapabilities SupportedContacts = new Windows.Devices.Input.TouchCapabilities();

        uint numActiveContacts;
        Dictionary<uint, Windows.UI.Input.PointerPoint> contacts;
        Dictionary<uint, Point> startLocation;
        Dictionary<uint, bool> pointSwiped;
        int swipeThresholdX = 100;
        int swipeThresholdY = 100;

        public MainPage()
        {
            this.InitializeComponent();
            numActiveContacts = 0;
            contacts = new Dictionary<uint, Windows.UI.Input.PointerPoint>((int)SupportedContacts.Contacts);
            startLocation = new Dictionary<uint, Point>((int)SupportedContacts.Contacts);
            pointSwiped = new Dictionary<uint, bool>((int)SupportedContacts.Contacts);
            targetContainer.PointerPressed += new PointerEventHandler(targetContainer_PointerPressed);
            targetContainer.PointerEntered += new PointerEventHandler(targetContainer_PointerEntered);
            targetContainer.PointerReleased += new PointerEventHandler(targetContainer_PointerReleased);
            targetContainer.PointerExited += new PointerEventHandler(targetContainer_PointerExited);
            targetContainer.PointerCanceled += new PointerEventHandler(targetContainer_PointerCanceled);
            targetContainer.PointerCaptureLost += new PointerEventHandler(targetContainer_PointerCaptureLost);
            targetContainer.PointerMoved += new PointerEventHandler(targetContainer_PointerMoved);
        }

        // PointerPressed and PointerReleased events do not always occur in pairs. 
        // Your app should listen for and handle any event that might conclude a pointer down action 
        // (such as PointerExited, PointerCanceled, and PointerCaptureLost).
        void targetContainer_PointerPressed(object sender, PointerRoutedEventArgs e)
        {
            if (Convert.ToBoolean(SupportedContacts.TouchPresent) && (numActiveContacts > SupportedContacts.Contacts))
            {
                // cannot support more contacts
                eventLog.Text += "
Number of contacts exceeds the number supported by the device.";
                return;
            }

            Windows.UI.Input.PointerPoint pt = e.GetCurrentPoint(targetContainer);

            // Update event sequence.
            eventLog.Text += "
Down: " + pt.PointerId;

            // Change background color of target when pointer contact detected.
            targetContainer.Fill = new SolidColorBrush(Windows.UI.Colors.Green);

            // Check if pointer already exists (if enter occurred prior to down).
            if (contacts.ContainsKey(pt.PointerId))
            {
                return;
            }
            contacts[pt.PointerId] = pt;
            startLocation[pt.PointerId] = pt.Position;
            pointSwiped[pt.PointerId] = false;
            ++numActiveContacts;
            e.Handled = true;

            // Display pointer details.
            createInfoPop(e);
        }

        private void targetContainer_PointerEntered(object sender, PointerRoutedEventArgs e)
        {
            Windows.UI.Input.PointerPoint pt = e.GetCurrentPoint(targetContainer);

            // Update event sequence.
            eventLog.Text += "
Over: " + pt.PointerId;

            if (contacts.Count == 0)
            {
                // Change background color of target when pointer contact detected.
                targetContainer.Fill = new SolidColorBrush(Windows.UI.Colors.Blue);
            }

            // Check if pointer already exists (if enter occurred prior to down).
            if (contacts.ContainsKey(pt.PointerId))
            {
                return;
            }

            // Push new pointer Id onto expando target pointers array.
            contacts[pt.PointerId] = pt;
            startLocation[pt.PointerId] = pt.Position;
            pointSwiped[pt.PointerId] = false;
            ++numActiveContacts;
            e.Handled = true;

            // Display pointer details.
            createInfoPop(e);
        }

        // Fires for for various reasons, including: 
        //    - User interactions
        //    - Programmatic caputre of another pointer
        //    - Captured pointer was deliberately released
        // PointerCaptureLost can fire instead of PointerReleased. 
        private void targetContainer_PointerCaptureLost(object sender, PointerRoutedEventArgs e)
        {
            Windows.UI.Input.PointerPoint pt = e.GetCurrentPoint(targetContainer);

            // Update event sequence.
            eventLog.Text += "
Pointer capture lost: " + pt.PointerId;

            if (contacts.ContainsKey(pt.PointerId))
            {
                checkSwipe();
                contacts[pt.PointerId] = null;
                contacts.Remove(pt.PointerId);
                startLocation.Remove(pt.PointerId);
                if (pointSwiped.ContainsKey(pt.PointerId))
                    pointSwiped.Remove(pt.PointerId);

                --numActiveContacts;
            }

            // Update the UI and pointer details.
            foreach (TextBlock tb in pointerInfo.Children)
            {
                if (tb.Name == e.Pointer.PointerId.ToString())
                {
                    pointerInfo.Children.Remove(tb);
                }
            }

            if (contacts.Count == 0)
            {
                targetContainer.Fill = new SolidColorBrush(Windows.UI.Colors.Black);
            }

            e.Handled = true;
        }

        // Fires for for various reasons, including: 
        //    - A touch contact is canceled by a pen coming into range of the surface.
        //    - The device doesn't report an active contact for more than 100ms.
        //    - The desktop is locked or the user logged off. 
        //    - The number of simultaneous contacts exceeded the number supported by the device.
        private void targetContainer_PointerCanceled(object sender, PointerRoutedEventArgs e)
        {
            Windows.UI.Input.PointerPoint pt = e.GetCurrentPoint(targetContainer);

            // Update event sequence.
            eventLog.Text += "
Pointer canceled: " + pt.PointerId;

            if (contacts.ContainsKey(pt.PointerId))
            {
                checkSwipe();
                contacts[pt.PointerId] = null;
                contacts.Remove(pt.PointerId);
                startLocation.Remove(pt.PointerId);
                if (pointSwiped.ContainsKey(pt.PointerId))
                    pointSwiped.Remove(pt.PointerId);

                --numActiveContacts;
            }

            // Update the UI and pointer details.
            foreach (TextBlock tb in pointerInfo.Children)
            {
                if (tb.Name == e.Pointer.PointerId.ToString())
                {
                    pointerInfo.Children.Remove(tb);
                }
            }

            if (contacts.Count == 0)
            {
                targetContainer.Fill = new SolidColorBrush(Windows.UI.Colors.Black);
            }

            e.Handled = true;
        }

        private void targetContainer_PointerExited(object sender, PointerRoutedEventArgs e)
        {
            Windows.UI.Input.PointerPoint pt = e.GetCurrentPoint(targetContainer);

            // Update event sequence.
            eventLog.Text += "
Pointer exited: " + pt.PointerId;

            if (contacts.ContainsKey(pt.PointerId))
            {
                checkSwipe();
                contacts[pt.PointerId] = null;
                contacts.Remove(pt.PointerId);
                startLocation.Remove(pt.PointerId);
                if (pointSwiped.ContainsKey(pt.PointerId))
                    pointSwiped.Remove(pt.PointerId);

                --numActiveContacts;
            }

            // Update the UI and pointer details.
            foreach (TextBlock tb in pointerInfo.Children)
            {
                if (tb.Name == e.Pointer.PointerId.ToString())
                {
                    pointerInfo.Children.Remove(tb);
                }
            }

            if (contacts.Count == 0)
            {
                targetContainer.Fill = new SolidColorBrush(Windows.UI.Colors.Gray);

            }
            e.Handled = true;
        }

        /// <summary>
        /// Invoked when this page is about to be displayed in a Frame.
        /// </summary>
        /// <param name="e">Event data that describes how this page was reached.  The Parameter
        /// property is typically used to configure the page.</param>
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
        }

        void targetContainer_PointerReleased(object sender, PointerRoutedEventArgs e)
        {
            foreach (TextBlock tb in pointerInfo.Children)
            {
                if (tb.Name == e.Pointer.PointerId.ToString())
                {
                    pointerInfo.Children.Remove(tb);
                }
            }

            Windows.UI.Input.PointerPoint pt = e.GetCurrentPoint(targetContainer);

            // Update event sequence.
            eventLog.Text += "
Up: " + pt.PointerId;

            // Change background color of target when pointer contact detected.
            targetContainer.Fill = new SolidColorBrush(Windows.UI.Colors.Red);

            if (contacts.ContainsKey(pt.PointerId))
            {
                checkSwipe();
                contacts[pt.PointerId] = null;
                contacts.Remove(pt.PointerId);
                startLocation.Remove(pt.PointerId);
                if(pointSwiped.ContainsKey(pt.PointerId))
                    pointSwiped.Remove(pt.PointerId);

                --numActiveContacts;
            }
            e.Handled = true;
        }

        private void targetContainer_PointerMoved(object sender, PointerRoutedEventArgs e)
        {
            Windows.UI.Input.PointerPoint currentPoint = e.GetCurrentPoint(targetContainer);
            if (currentPoint.IsInContact)
            {
                if (startLocation.ContainsKey(currentPoint.PointerId))
                {
                    Point startPoint = startLocation[currentPoint.PointerId];
                    if (Math.Abs(currentPoint.Position.X - startPoint.X) > swipeThresholdX) // I only did one Axis for testing
                    {
                        pointSwiped[currentPoint.PointerId] = true;
                    }
                }

            }
            updateInfoPop(e);
        }

        int numberOfSwipedFingers()
        {
            int count = 0;
            foreach (var item in pointSwiped)
            {
                if (item.Value) { count += 1; }
            }
            return count;
        }

        void checkSwipe()
        {
            int fingers = numberOfSwipedFingers();
            if (fingers > 1)
            {
                eventLog.Text += "
Number of Swiped fingers = " + fingers;
            }
            else if (fingers == 1)
            {
                eventLog.Text += "
Number of Swiped fingers = " + fingers;
            }
            if(fingers > 0)
                pointSwiped.Clear();
        }            

        void createInfoPop(PointerRoutedEventArgs e)
        {
            Windows.UI.Input.PointerPoint currentPoint = e.GetCurrentPoint(targetContainer);
            TextBlock pointerDetails = new TextBlock();
            pointerDetails.Name = currentPoint.PointerId.ToString();
            pointerDetails.Foreground = new SolidColorBrush(Windows.UI.Colors.White);
            pointerInfo.Children.Add(pointerDetails);
            pointerDetails.Text = queryPointer(e);
        }

        void updateInfoPop(PointerRoutedEventArgs e)
        {
            foreach (TextBlock pointerDetails in pointerInfo.Children)
            {
                if (pointerDetails.Name == e.Pointer.PointerId.ToString())
                {
                    pointerDetails.Text = queryPointer(e);
                }
            }
        }

        String queryPointer(PointerRoutedEventArgs e)
        {
            Windows.UI.Input.PointerPoint currentPoint = e.GetCurrentPoint(targetContainer);
            String details = "";
            switch (e.Pointer.PointerDeviceType)
            {
                case Windows.Devices.Input.PointerDeviceType.Mouse:
                    details += "
Pointer type: mouse";
                    break;
                case Windows.Devices.Input.PointerDeviceType.Pen:
                    details += "
Pointer type: pen";
                    if (e.Pointer.IsInContact)
                    {
                        details += "
Pressure: " + currentPoint.Properties.Pressure;
                        details += "
rotation: " + currentPoint.Properties.Orientation;
                        details += "
Tilt X: " + currentPoint.Properties.XTilt;
                        details += "
Tilt Y: " + currentPoint.Properties.YTilt;
                        details += "
Barrel button pressed: " + currentPoint.Properties.IsBarrelButtonPressed;
                    }
                    break;
                case Windows.Devices.Input.PointerDeviceType.Touch:
                    details += "
Pointer type: touch";
                    details += "
rotation: " + currentPoint.Properties.Orientation;
                    details += "
Tilt X: " + currentPoint.Properties.XTilt;
                    details += "
Tilt Y: " + currentPoint.Properties.YTilt;
                    break;
                default:
                    details += "
Pointer type: n/a";
                    break;
            }

            GeneralTransform gt = targetContainer.TransformToVisual(page);
            Point screenPoint;

            screenPoint = gt.TransformPoint(new Point(currentPoint.Position.X, currentPoint.Position.Y));
            details += "
Pointer Id: " + currentPoint.PointerId.ToString() +
                "
Pointer location (parent): " + currentPoint.Position.X + ", " + currentPoint.Position.Y +
                "
Pointer location (screen): " + screenPoint.X + ", " + screenPoint.Y;
            return details;
        }
    }
}

这篇关于在 WinRT 应用程序中处理两指、三指、四指滑动手势的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆