zoukankan      html  css  js  c++  java
  • WPF触控程序开发(二)——整理的一些问题

      上一篇(WPF触控程序开发)介绍了几个比较不错的资源,比较基础。等到自己真正使用它们时,问题就来了,现把我遇到的几个问题罗列下,大家如有遇到其他问题或者有什么好的方法还望赐教。

      问题1.如何获取触控点的个数

      当你要在单指触屏和多指触屏时分别做不同的处理时就要用到。如何获取,刚开始我是弄个List,在TouchDown时存储输入点,然后TouchUp时移除输入点,这样我要判断输入点的个数时只要获取这个List的Count就行了,这是原始的做法,而且有的时候会不准(原因可能是down和up的事件抛出时机导致的,具体原因没作研究),有个比较简单的做法是在开头引用一下 

    using System.Linq ;

    ManipulationStarting或者ManipulationDelta里可以使用

    int deviceCount = e.Manipulators.Count();

    来获取即可。

      问题2.如何判断触控点是否位移

      这个问题也常遇到,情景是在单点抬起和单点移动再抬起做不同的处理,如单点抬起就弹窗,单点移动后抬起做翻页,如何判断呢?其实我上篇也略微提到了,就是定义一个TouchPoint类型的变量

    TouchPoint touchPointOld;

    TouchDown的时候

    touchPointOld  = e.GetTouchPoint(this);

    然后在TouchUp的时候获取新点

    TouchPoint touchPointNew = e.GetTouchPoint(this);

    最后即可判断X轴的位移

    double offsetX = touchPointNew.Bounds.Left - touchPointOld.Bounds.Left ;//判断X轴位移
      当然也可以判断Y轴的位移。在这里多说一句,当我们在用鼠标模拟触控测试时,是可以很精准地落下抬起,现实当中的手指落下抬起,虽然用户主观上没有动,实际上可能会有5个像素左右的位移(手指是肉团,没有鼠标那么精细),这时代码就要判定超过5个像素的移动才算手指位移了。
     
      问题3.如何做精准的翻页效果

      WPF的ScrollViewer已经支持触屏了,设置PanningMode属性即可滑动,但是这样滑动是利用了惯性,想要控制精准翻页比较困难。想做到像iphone相册那样的翻页效果,即不管使用多大力气,滑一次只翻一屏,这显然不适用。目前我能想到的是用动画来处理,大致思路是把罗列的对象放置于Canvas里(必须是Canvas,原因后面再说),然后使用DoubleAnimation作用于这个Canvas的TranslateTransform.XProperty,为避免生硬地滑动,可以设置DoubleAnimation的AccelerationRatio和DecelerationRatio,这样能有加速和减速的效果。每次手指放下记录点,抬起后判断位移趋势是左移还是右移,然后执行相应的动画,当然,每次滑动多少就要自己计算了。

      上面说到了一定要使用Canvas,当然你也可以用Gird、StackPanel等等、不过你会发现,只要执行移动动画,整个容器就会从你的视线消失。这可能与容器的特性有关,当你设置容器的宽度后(假设是水平滑动),执行动画,改变TranslateTransform.XProperty,容器好像不是按照你的原来意思来滑动,而是把初始化的时候显示的部分整体移动了,不管你设的宽度为多少,而Canvas则会像一张很长的画布一样慢慢展开。这个现象很容易重现,在blend里随意试一下,设置容器转换的X值(其实就是TranslateTransform.XProperty),你会很清晰得看到全过程。

      问题4.如何做图片的平移、缩放、旋转

      我认为这可以算触控开发的进阶了。因为这个涉及到操作一个原始的结构体——UI的Matrix。当然你想简单做做的话直接用Blend自带的TranslateZoomRotateBehavior就行,不过使用这个的话就相当于完全托管了,你能控制的东西很少。所以还是要直接操作Matrix。关于Matrix的介绍这里有个资源可以参考一下:WPF中的MatrixTransform

      不必研究很深入,你只需要知道Matrix有6个值,分别是M11,M12,M21,M22,OffsetX,OffsetY,其中M11和M22分别管的X轴和Y轴的缩放,OffsetX对应X轴位移,OffsetY对应Y轴位移,还有ScaleAt方法(缩放),Translate方法(平移),RotateAt方法(旋转),看他们的传入参数,基本都可以从e获取,如ScaleAt方法需要四个参数:

    public void ScaleAt (double scaleX, double scaleY , double centerX , double centerY );

    一般做平移、旋转、缩放的时候是写在ManipulationDelta里面,前面两个参数就可以从e的DeltaManipulation属性获得,为Scale.X和Scale.Y,后面两个参数就更简单了,是操作的中心点,也可以从e获得,ManipulationOrigin属性即为中心点,直接把他的X和Y传入就行。

      还要多说一句,这里的Matrix改变后,并不影响UI的Width或者ActualWidth,如果想要获取这类的值,需要计算。有这样的情景,我需要在缩放到某个尺寸后就不让继续缩放了,这时候你去获取UI的Width或者ActualWidth根本没用,因为这些值一直没变过。我的做法是定义全局变量,每次ManipulationDelta里改变的时候,就计算缩放后的新值,以此来记录当前缩放状态。其中ManipulationDelta的Scale.X就是X轴每次缩放的比例值。

      懂了这些,我认为已经算入门了。不过我也研究过iphone相册的效果,它好像不是我这样的思路。首先,它的滑动是实时跟随的,当然我也可以做到那样的效果;其次它的黑边处理,是等宽填充,即不管相片多宽多高,宽度是始终充满屏幕的,当你滑动时,不仅当前图片跟随移动,紧挨着的图片也会受影响,而我的只是处理当前的对象,并未去影响其他的。这也可能是操作系统的区别吧,IOS没研究过,说不定它是一个封好的控件,任何对象放进去就会有这样的效果。我看了新浪、QQ的IOS客户端,里面的图片展示都是这样的效果,看起来好容易。不过我相信,任何的效果都是代码实现的,看起来越简单,其实实现过程并不是那么简单。IOS对我来说只是一个黑盒,我能模仿,甚至超越。
  • 相关阅读:
    AcWing 157. 树形地铁系统 (hash判断树同构)打卡
    AcWing 156. 矩阵 (哈希二维转一维查询)打卡
    AcWing 144. 最长异或值路径 01字典树打卡
    AcWing 143. 最大异或对 01字典树打卡
    AcWing 142. 前缀统计 字典树打卡
    AcWing 139. 回文子串的最大长度 hash打卡
    AcWing 138. 兔子与兔子 hash打卡
    常用C库函数功能及用法
    编程实现C库函数
    C语言面试题5
  • 原文地址:https://www.cnblogs.com/zoexia/p/3670720.html
Copyright © 2011-2022 走看看