zoukankan      html  css  js  c++  java
  • WPF4多点触摸事件

    UIElement在WPF4下添加了很多支持多点触摸的事件,通过它们可以在硬件支持的情况下处理多点触摸,以下通过代码来说明通过处理这些事件,我们可以做些什么:

    一.触摸相关的多种事件,跟鼠标事件是对应的,通过这些事件可以获取到多个触摸的鼠标点,并进行相应的处理

    • public static readonly RoutedEvent TouchDownEvent;
    • public static readonly RoutedEvent TouchEnterEvent;
    • public static readonly RoutedEvent TouchLeaveEvent;
    • public static readonly RoutedEvent TouchMoveEvent;
    • public static readonly RoutedEvent TouchUpEvent;

      以上每个事件都包含一个TouchEventArgs参数,通过该参数可以获取到一个TouchDevice信息,对应于每一次触摸,还可以通过GetTouchPoint得到一个TouchPoint,TouchPoint包含当前触摸的动作,触摸的位置等信息,通过获取到的TouchDevice,我们可以处理每一次触摸(通过判断TouchDevice的ID号来分辨不同的触摸),并通过TouchPoint获取触摸的坐标点,从而实现一些多点的逻辑,例如多点的书写(通过获取的TouchPoint来生成PathFigure,形成PathGeometry,最终填充成Path来绘制)

      二.Manipulation事件,通过这些事件可以实现UIElement的一些多点手势(移动,旋转,缩放)

    • public static readonly RoutedEvent ManipulationCompletedEven;
    • public static readonly RoutedEvent ManipulationDeltaEvent;
    • public static readonly RoutedEvent ManipulationInertiaStartingEvent;
    • public static readonly RoutedEvent ManipulationStartedEvent;

      1.要处理Manipulation事件,首先必须设置UIElement的IsManipulationEnabled为true

      2.ManipulationInertiaStartingEvent事件包含一个ManipulationStartingEventArgs参数,通过该参数可以设置:

      UIElement的ManipulationContainer —— 设置该UIElement的容器

      Mode —— 处理的事件类型,包含以下枚举

      None:不处理

      TranslateX:处理水平移动

      TranslateY:处理垂直移动

      Translate:处理移动

      Rotate:处理旋转

      Scale:处理缩放

      All:处理所有事件

      3.要实现控件的移动,缩放,旋转,可以在控件的ManipulationDeltaEvent事件中使用以下代码:

       private void image_ManipulationDelta(object sender, ManipulationDeltaEventArgs e)
              {
                  var element = e.Source as FrameworkElement;
                  if (element != null)
                  {
                      try
                      {
                          ManipulationDelta deltaManipulation = e.DeltaManipulation;
                          Matrix matrix = element.RenderTransform.Value;
                          Point center = new Point(element.ActualWidth / 2, element.ActualHeight / 2); 
                          center = matrix.Transform(center);  //设置中心点
                          //处理缩放
                          matrix.ScaleAt(deltaManipulation.Scale.X, deltaManipulation.Scale.Y, center.X, center.Y);
                          // 处理旋转
                          matrix.RotateAt(e.DeltaManipulation.Rotation, center.X, center.Y);
                          //处理移动

                          matrix.Translate(e.DeltaManipulation.Translation.X, e.DeltaManipulation.Translation.Y);

                          element.RenderTransform = new MatrixTransform(matrix);

                          e.Handled = true;
                      }
                      catch (Exception ei)
                      {
                          MessageBox.Show(ei.ToString());
                      }
                  }

              }

      4.此外可以在ManipulationInertiaStarting事件中设置惯性效果

      private void image_ManipulationInertiaStarting(object sender, ManipulationInertiaStartingEventArgs e)
              {
                  // 移动惯性
                  e.TranslationBehavior = new InertiaTranslationBehavior()
                  {
                      InitialVelocity = e.InitialVelocities.LinearVelocity,
                      DesiredDeceleration = 1 / (1000.0 * 1000.0)   // 单位:一个WPF单位 / ms
                  };

                  // 缩放惯性
                  e.ExpansionBehavior = new InertiaExpansionBehavior()
                  {
                      InitialVelocity = e.InitialVelocities.ExpansionVelocity,
                      DesiredDeceleration = 1 / 1000.0 * 1000.0   // 单位:一个WPF单位 / ms
                  };

                  // 旋转惯性
                  e.RotationBehavior = new InertiaRotationBehavior()
                  {
                      InitialVelocity = e.InitialVelocities.AngularVelocity,
                      DesiredDeceleration = 720 / (1000.0 * 1000.0)  //单位:一个角度 / ms
                  };
                  e.Handled = true;
              }

      5.在设置了惯性事件后,如果不处理判断控件容器的边界,那很容易一个移动就会把控件移到屏幕外部,因此此时可以在ManipulationDeltaEvent事件中加入以下代码:

         if (e.IsInertial)
         {
                 Rect containingRect = new Rect(((FrameworkElement)e.ManipulationContainer).RenderSize);

                 Rect shapeBounds = element.RenderTransform.TransformBounds(new Rect(element.RenderSize));
                 if (e.IsInertial && !containingRect.Contains(shapeBounds))
                 {
                       e.ReportBoundaryFeedback(e.DeltaManipulation);    
                       e.Complete();
                  }
          }    

      三.总结

      WPF4直接加入了Manipulation事件来支持对UIElement手势的移动,旋转和缩放,也加入了各种触摸事件来处理多个点的触摸,通过这些事件可以获取到多点触摸的坐标,从而实现各种多点逻辑

  • 相关阅读:
    记Spring搭建功能完整的个人博客「Oyster」全过程[其二] Idea中Maven+SpringBoot多模块项目开发的设计和各种坑(模块间依赖和打包问题)
    记Spring搭建功能完整的个人博客「Oyster」全过程[其一] 整体思路:需求、架构及技术要求
    [总结-动态规划]经典DP状态设定和转移方程
    HDU-6217 BBP Formula 脑洞
    UVA-11426 GCD
    UVA-11806 Cheerleaders 计数问题 容斥定理
    CodeForces-546D Soldier and Number Game 筛法+动态规划
    CodeForces-148D Bag of mice 概率dp
    Gym-101615D Rainbow Roads 树的DFS序 差分数组
    AVL树 算法思想与代码实现
  • 原文地址:https://www.cnblogs.com/milk/p/2421233.html
Copyright © 2011-2022 走看看