Csharp/C#教程:处理两个,三个,四个手指在WinRT应用程序中滑动手势分享


处理两个,三个,四个手指在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个手指轻扫手势。 谁能告诉我怎么做?

根据此MSDN论坛发布,您将需要使用指针通知。 带有工作示例代码的文档位于MSDN Library中

从上一个链接:

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


只是一个警告,我没有多点触控Windows 8设备来测试此代码。 所以它已经在Simuator中进行了测试,具有所有限制,并且正如上面提到的链接,Windows 8没有内置的手势支持来检测多个手指,你必须使用较低级别的function。

首先,我在上面的MSDN示例代码中添加了两个字典,并为您的Swipe Threshold添加了两个变量到类定义。

 Dictionary startLocation; Dictionary pointSwiped; int swipeThresholdX = 100; int swipeThresholdY = 100; 

然后我在Form的构造函数中初始化Dictionarys

 startLocation = new Dictionary((int)SupportedContacts.Contacts); pointSwiped = new Dictionary((int)SupportedContacts.Contacts); 

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

添加:

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

删除:

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

然后最后将它们放在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示例:

 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 https://go.microsoft.com/fwlink/?LinkId=234238 namespace PointerInput { ///  /// An empty page that can be used on its own or navigated to within a Frame. ///  public sealed partial class MainPage : Page { Windows.Devices.Input.TouchCapabilities SupportedContacts = new Windows.Devices.Input.TouchCapabilities(); uint numActiveContacts; Dictionary contacts; Dictionary startLocation; Dictionary pointSwiped; int swipeThresholdX = 100; int swipeThresholdY = 100; public MainPage() { this.InitializeComponent(); numActiveContacts = 0; contacts = new Dictionary((int)SupportedContacts.Contacts); startLocation = new Dictionary((int)SupportedContacts.Contacts); pointSwiped = new Dictionary((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 += "nNumber of contacts exceeds the number supported by the device."; return; } Windows.UI.Input.PointerPoint pt = e.GetCurrentPoint(targetContainer); // Update event sequence. eventLog.Text += "nDown: " + 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 += "nOver: " + 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 += "nPointer 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 += "nPointer 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 += "nPointer 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; } ///  /// Invoked when this page is about to be displayed in a Frame. ///  /// Event data that describes how this page was reached. The Parameter /// property is typically used to configure the page. 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 += "nUp: " + 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 += "nNumber of Swiped fingers = " + fingers; } else if (fingers == 1) { eventLog.Text += "nNumber 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 += "nPointer type: mouse"; break; case Windows.Devices.Input.PointerDeviceType.Pen: details += "nPointer type: pen"; if (e.Pointer.IsInContact) { details += "nPressure: " + currentPoint.Properties.Pressure; details += "nrotation: " + currentPoint.Properties.Orientation; details += "nTilt X: " + currentPoint.Properties.XTilt; details += "nTilt Y: " + currentPoint.Properties.YTilt; details += "nBarrel button pressed: " + currentPoint.Properties.IsBarrelButtonPressed; } break; case Windows.Devices.Input.PointerDeviceType.Touch: details += "nPointer type: touch"; details += "nrotation: " + currentPoint.Properties.Orientation; details += "nTilt X: " + currentPoint.Properties.XTilt; details += "nTilt Y: " + currentPoint.Properties.YTilt; break; default: details += "nPointer type: n/a"; break; } GeneralTransform gt = targetContainer.TransformToVisual(page); Point screenPoint; screenPoint = gt.TransformPoint(new Point(currentPoint.Position.X, currentPoint.Position.Y)); details += "nPointer Id: " + currentPoint.PointerId.ToString() + "nPointer location (parent): " + currentPoint.Position.X + ", " + currentPoint.Position.Y + "nPointer location (screen): " + screenPoint.X + ", " + screenPoint.Y; return details; } } } 

我将Mark Hall的答案改编成了一个单独的课程,并处理向上,向下,向左和向右滑动。 它仍有问题,你可以在不同的时间举起手指并获得多个事件并可以改进,虽然它适合我的需要:

 public enum DirectionSwiped { None, Up, Down, Left, Right } public class SwipeEventArgs : EventArgs { public DirectionSwiped Direction { get; set; } public int NumberOfTouches { get; set; } } public class SwipeGestureDetector { public EventHandler SwipeDetected; // How much of the grid needs to be covered by the swipe? private const double SWIPE_THRESHOLD = 0.5; // How much drift is allowed in the opposite axis? private const int ALLOWED_DRIFT = 100; Windows.Devices.Input.TouchCapabilities SupportedContacts = new Windows.Devices.Input.TouchCapabilities(); uint numActiveContacts; Dictionary contacts; Dictionary startLocation; Dictionary pointSwiped; private Grid mGrid; public SwipeGestureDetector(Grid grid) { mGrid = grid; numActiveContacts = 0; contacts = new Dictionary((int)SupportedContacts.Contacts); startLocation = new Dictionary((int)SupportedContacts.Contacts); pointSwiped = new Dictionary((int)SupportedContacts.Contacts); grid.PointerPressed += new PointerEventHandler(Grid_PointerPressed); grid.PointerEntered += new PointerEventHandler(Grid_PointerEntered); grid.PointerReleased += new PointerEventHandler(Grid_PointerReleased); grid.PointerExited += new PointerEventHandler(Grid_PointerExited); grid.PointerCanceled += new PointerEventHandler(Grid_PointerCanceled); grid.PointerCaptureLost += new PointerEventHandler(Grid_PointerCaptureLost); grid.PointerMoved += new PointerEventHandler(Grid_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 Grid_PointerPressed(object sender, PointerRoutedEventArgs e) { if (Convert.ToBoolean(SupportedContacts.TouchPresent) && (numActiveContacts > SupportedContacts.Contacts)) { // cannot support more contacts Debug.WriteLine("nNumber of contacts exceeds the number supported by the device."); return; } Windows.UI.Input.PointerPoint pt = e.GetCurrentPoint(mGrid); // 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] = DirectionSwiped.None; ++numActiveContacts; e.Handled = true; } private void Grid_PointerEntered(object sender, PointerRoutedEventArgs e) { Windows.UI.Input.PointerPoint pt = e.GetCurrentPoint(mGrid); // 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] = DirectionSwiped.None; ++numActiveContacts; e.Handled = true; } // 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 Grid_PointerCaptureLost(object sender, PointerRoutedEventArgs e) { Windows.UI.Input.PointerPoint pt = e.GetCurrentPoint(mGrid); 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; } // 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 Grid_PointerCanceled(object sender, PointerRoutedEventArgs e) { Windows.UI.Input.PointerPoint pt = e.GetCurrentPoint(mGrid); 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 Grid_PointerExited(object sender, PointerRoutedEventArgs e) { Windows.UI.Input.PointerPoint pt = e.GetCurrentPoint(mGrid); 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; } void Grid_PointerReleased(object sender, PointerRoutedEventArgs e) { Windows.UI.Input.PointerPoint pt = e.GetCurrentPoint(mGrid); 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 Grid_PointerMoved(object sender, PointerRoutedEventArgs e) { Windows.UI.Input.PointerPoint currentPoint = e.GetCurrentPoint(mGrid); if (currentPoint.IsInContact) { if (startLocation.ContainsKey(currentPoint.PointerId)) { Point startPoint = startLocation[currentPoint.PointerId]; // Compare startPoint to current location and determine if that point did a swipe? double horizontalMovement = currentPoint.Position.X - startPoint.X; double verticalMovement = currentPoint.Position.Y - startPoint.Y; double horizontalDistance = Math.Abs(horizontalMovement); double verticalDistance = Math.Abs(verticalMovement); double requiredLeftMovement = mGrid.ActualWidth * SWIPE_THRESHOLD * -1; double requiredRightMovement = mGrid.ActualWidth * SWIPE_THRESHOLD; double requiredUpMovement = mGrid.ActualHeight * SWIPE_THRESHOLD * -1; double requiredDownMovement = mGrid.ActualHeight * SWIPE_THRESHOLD; if (verticalMovement < requiredUpMovement && horizontalDistance < 100) { pointSwiped[currentPoint.PointerId] = DirectionSwiped.Up; } else if (verticalMovement > requiredDownMovement && horizontalDistance < ALLOWED_DRIFT) { pointSwiped[currentPoint.PointerId] = DirectionSwiped.Down; } else if (horizontalMovement > requiredRightMovement && verticalDistance < ALLOWED_DRIFT) { pointSwiped[currentPoint.PointerId] = DirectionSwiped.Right; } else if (horizontalMovement < requiredLeftMovement && verticalDistance < ALLOWED_DRIFT) { pointSwiped[currentPoint.PointerId] = DirectionSwiped.Left; } } } } void checkSwipe() { NotififyListenerIfSwiped(DirectionSwiped.Up); NotififyListenerIfSwiped(DirectionSwiped.Down); NotififyListenerIfSwiped(DirectionSwiped.Left); NotififyListenerIfSwiped(DirectionSwiped.Right); } private void NotififyListenerIfSwiped(DirectionSwiped direction) { int fingers = numberOfSwipedFingers(direction); if (fingers >= 1) { if (SwipeDetected != null) { SwipeDetected(this, new SwipeEventArgs() { Direction = direction, NumberOfTouches = fingers }); } } if (fingers > 0) pointSwiped.Clear(); } int numberOfSwipedFingers(DirectionSwiped direction) { int count = 0; foreach (var item in pointSwiped) { DirectionSwiped swipe = item.Value; if (swipe == direction) { count += 1; } } return count; } } 

用法

上述就是C#学习教程:处理两个,三个,四个手指在WinRT应用程序中滑动手势分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!

  public void Gesture_Detected(Object sender, SwipeEventArgs e) { Debug.WriteLine("Number of touches: " + e.NumberOfTouches + " Direction: " + e.Direction); } public MainPage() { this.InitializeComponent(); SwipeGestureDetector gestureDetector = new SwipeGestureDetector(this.rootGrid); gestureDetector.SwipeDetected += Gesture_Detected; 

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/cdevelopment/951020.html

(0)
上一篇 2021年11月18日
下一篇 2021年11月18日

精彩推荐