Window phone应用中的多触点手势解读以及toolKit.dll和Microsoft.Phone.dll 冲突问题

我最近在在写一个windowphone应用,应用中有关于单点触控,多点触控的需要。如点击,双击,滑动,双指滑动等,在这个过程中遇到了一些问题,在这里分享一下我的心得。

首先对windowphone的触控的各种方法做一下总结分析,我对此处问题大部分来自一Charles Petzold先生的解读,在此对Charles Petzold先生表示感谢。

                  手势服务和侦听器

    • 首先您需要安装 Windows Phone 7 开发工具,当然,还有 Silverlight for Windows Phone 工具包。

      安装工具包后,您可以通过添加对 Microsoft.Phone.Controls.Toolkit 程序集的引用来在您自己的 Windows Phone 项目中使用它。在“添加引用”对话框中,它将列在“.NET”选项卡的下面。

      然后,在 XAML 文件中,您需要如下所示的 XML 命名空间声明(但所有内容位于一行):

      
           xmlns:toolkit=
      "clr-namespace:Microsoft.Phone.Controls;
      assembly=Microsoft.Phone.Controls.Toolkit"
          

      以下是 12 个可用的手势事件,我将按大致顺序对其进行讨论(我将其分组到同一行的事件是相关的,而且发生顺序相同):

      
           GestureBegin, GestureCompleted
      Tap
      DoubleTap
      Hold
      DragStarted, DragDelta, DragCompleted
      Flick
      PinchStarted, PinchDelta, PinchCompleted
          

      假设您要处理发生在 Grid 或任何子 Grid 的 Tap 和 Hold 事件。您可以在 XAML 文件中进行指定,指定方法如下所示:

      
           <Grid ...
           >
       <toolkit:GestureService.GestureListener>
        <toolkit:GestureListener 
         Tap="OnGestureListenerTap"
         Hold="OnGestureListenerHold" />
       </toolkit:GestureService.GestureListener>
        ...
           </Grid>
          

      您在 GestureListener 标记中指定事件和处理程序,此标记是 GestureService 类的 GestureListener 附加属性的子项。

      此外,在代码中,您将需要用于 Microsoft.Phone.Controls 命名空间的命名空间指令和以下代码:

      
           GestureListener gestureListener = 
       GestureService.GetGestureListener(element);
      
      gestureListener.Tap += OnGestureListenerTap;
      gestureListener.Hold += OnGestureListenerHold;
          

      不管是哪种情况,如果要在面板上设置此手势侦听器,请确保至少将 Background 属性设为 Transparent!事件将通过一个默认背景为空的面板来实现。

      如果你已经做了上述的部分你就可以进行基本的触控了,其余10中触控和上述两种(Tap,Hold)触控用法是基本一致的,下面我将对其中的要点进行解读。
       Tap 和 Hold

      所有手势事件都附带类型为 GestureEventArgs 或从 GestureEventArgs 派生的类型的事件参数。OriginalSource 属性指示碰到屏幕的第一根手指触摸到的最顶层的元素;GetPosition 方法提供这根手指相对于任何元素的当前坐标。

      可对手势事件进行路由,这意味着它们可以在可视树中传递,并且可以针对安装了 GestureListener 的任何元素进行处理。与往常一样,事件处理程序可以将 GestureEventArgs 的 Handled 属性设置为 true,以防止事件在可视树中进一步传递。但是,这只能影响使用这些手势事件的其他元素。将 Handled 设置为 true 并不能防止可视树中较高级别的元素通过其他界面获取触控输入。

      GestureBegin 事件指示有手指触摸了以前手指未触摸到的屏幕;当所有手指都离开屏幕后,GestureCompleted 会发出信号。这些事件可以为初始化或清理提供便利,但是您通常会更关注在这两个事件之间发生的手势事件。

      我不会在较简单的手势上花费太多的时间。当有手指触摸屏幕,然后在大约 1.1 秒内抬起,并且手指从原始位置并未移动很远时,会发生 Tap。如果相继两次点击的时间间隔太短,那么第二次点击会被当作 DoubleTap 接收。当有手指在屏幕上按下并在大致相同的位置停留大约 1.1 秒时会发生 Hold。Hold 事件在这个时间结束时生成,不需要等到手指离开屏幕。

      Drag 和 Flick

      当有手指触摸屏幕、在屏幕上移动或离开屏幕时会发生 Drag 序列(包含一个 DragStarted 事件、零个或更多 DragDelta 事件以及一个 DragCompleted 事件)。由于并不知道手指第一次触摸屏幕时会发生拖动操作,所以 DragStarted 事件会延迟到手指实际开始在 Tap 阈值外的范围移动时。如果将手指放在屏幕上,并在大约一秒内没有移动,则在 DragStarted 事件之前可能会先执行 Hold 事件。

      由于当引发 DragStarted 事件时手指已经开始移动,因此 DragStartedEventArgs 对象可以包含一个类型为 Orientation(水平或垂直)的 Direction 属性。DragDelta 事件附带的 DragDeltaEventArgs 对象包含更多信息:HorizontalChange 属性和 VerticalChange 属性(可以方便地添加到 TranslateTransform 的 X 属性和 Y 属性),或者 Canvas.Left 和 Canvas.Top 附加属性。

      当手指离开屏幕时如果手指仍在移动,表明用户想执行延时,此时会发生 Flick 事件。事件参数包含 Angle 值(从正 X 轴顺时针测量),以及 HorizontalVelocity 和 VerticalVelocity 值,它们都以像素/秒为单位。

      Flick 事件可以独立发生,可以在 DragStarted 和 DragCompleted 事件之间发生(无需任何 DragDelta 事件),也可以在一系列 DragDelta 事件之后 DragCompleted 事件之前发生。通常情况下,您需要将 Drag 事件与 Flick 事件一起处理,几乎就像 Flick 是 Drag 的延续一样。但是,您需要添加您自己的延时逻辑。

      DragAndFlick 项目中演示了这些操作过程。屏幕包含一个可以让用户用手指轻松地来回拖动的椭圆。如果使手指轻弹一下屏幕便离开屏幕,则会发生 Flick 事件,而且 Flick 处理程序会保存一些信息,并为 CompositionTarget.Rendering 事件安装一个处理程序。此事件(与视频显示刷新同步发生)使椭圆继续移动,但同时会降低移动速度。

      处理弹离边缘的操作有点特别:程序会保持一个位置,就好像椭圆一直在朝一个方向不断移动直至其停止;该位置包含在椭圆的弹跳区域内。

      Pinch双指触摸

      当有两根手指触摸屏幕时会发生 Pinch 序列;它通常被解释为扩展或收缩屏幕上的对象,也可能是对其进行旋转。

      毫无疑问,捏指操作是最令人捉摸不定的多点触控处理领域之一,而且更高级别的界面无法提供充足的信息也不罕见。众所周知,Windows Phone 7 ManipulationDelta 事件使用起来特别复杂。

      处理手势时,Drag 序列和 Pinch 序列是相互排斥的。它们不会重叠,但是它们可能会一个接一个地发生。例如,用一根手指触按屏幕,并拖动屏幕。这会生成一个 DragStarted 事件和多个 DragDelta 事件。现在用另一根手指触按屏幕。您将获得一个 DragCompleted 以结束 Drag 序列,该序列之后将发生一个 PinchStarted 事件和多个 PinchDelta 事件。现在保持第一根手指继续移动,但抬起第二根手指。这是一个用于结束 Pinch 序列的 PinchCompleted,接下来将发生 DragStarted 和 DragDelta。根据触摸屏幕的手指的数量,您基本上是在 Drag 序列和 Pinch 序列之间交替。

      此 Pinch 手势的一个有用特征是,它不会丢弃信息。您可以使用事件参数的属性完全重建两根手指的位置,这样,在需要时,您始终可以回到基本原理。

      在 Pinch 序列中,某根手指(让我们称其为主要手指)的当前位置在 GetPosition 方法中始终可用。在本次讨论中,我们称此返回值为 pt1。对于 PinchStarted 事件,PinchStartedGestureEventArgs 类具有两个附加属性,分别名为 Distance 和 Angle,用于指示第二根手指相对于第一根手指的位置。使用以下语句,您可以轻松地计算出此实际位置:

      1. Point pt2 = new Point(pt1.X + args.Distance * Cos(args.Angle),
      2. pt1.Y + args.Distance * Sin(args.Angle));

      Angle 属性以度为单位,因此在调用 Math.Cos 和 Math.Sin 之前,您需要使用 Cos 和 Sin 方法将其转换为弧度。在 PinchStarted 处理程序结束前,您还希望将 Distance 和 Angle 属性保存到名字可能是 pinchStartDistance 和 pinchStartAngle 的字段中。

      PinchDelta 事件附带一个 PinchGestureEventArgs 对象。同样,通过 GetPosition 方法您可以获得主要手指的位置,主要手指可能已经从其原来位置移动到其他位置。对于第二根手指,事件参数提供 DistanceRatio 和 TotalAngleDelta 属性。

      DistanceRatio 是手指之间的当前距离与原始距离的比率,也就是说,您可以按如下方式计算当前距离:

      1. double distance = args.DistanceRatio * pinchStartDistance;

      TotalAngleDelta 是手指之间的当前角度与原始角度之间的差异。您可以按如下方式计算当前角度:

      
           double angle = args.TotalAngleDelta + pinchStartAngle;
          

      现在您可以按照以前的方式计算第二根手指的位置:

      1. Point pt2 = new Point(pt1.X + distance * Cos(angle),
      2. pt1.Y + distance * Sin(angle));

      在 PinchDelta 处理期间,您不需要将任何附加信息保存到字段中来进一步处理 PinchDelta 事件。

      TwoFingerTracking 项目通过显示在屏幕上跟踪一根或两根手指的蓝色和绿色椭圆来演示此逻辑。

      到此对于触控尤其是多指触控就讲解完了。

      原文参考 https://msdn.microsoft.com/en-us/magazine/gg650664.aspx

      下面对LongListSelector同时存在于Toolkit.dll 和 Microsoft.Phone.dll中的问题提供解决方案

      如果你真的用了你可能会发现一个问题,longListSelector同时存在于ToolKit.dll与Microsoft.Phone.dll中,导致冲突。

      这是为什么呢?难道写.dll的人傻吗,原因是longlistselector最先存在于toolkit中,后来被wp官方收编了,于是就出现了该死的冲突。

      如你所想,像这类历史性问题多半会在新版本中得到解决。在wp7中存在冲突问题,而在wp8中这个问题得到解决了,所以安装wp8就好了。

      但是问题来了,wp7版的toolkit存在.msi文件点击直接安装,而wp8就没有相应的文件了所以安装方法就繁琐了一点在这了我只提供链接就好了上面有详细的介绍,只不过是英文的,考验英文水平了。

      安装链接 http://phone.codeplex.com/releases/view/107923

      这是安装说明先安装NuGet之后 安装Windows Phone Toolkit Package 方法是打开 vs 的Package manager Console

      输入 Install-Package WPtoolkit 。最后安装Multilingual App Toolkit for Visual Studio 这是一个.msi文件双击即可

       

原文地址:https://www.cnblogs.com/EDzhang/p/4374773.html