Windows Phone笔记(3)触摸简介(转)

Windows Phone笔记(3)触摸简介

 

  Windows Phone手机的屏幕非常灵敏,至少能够同时检测4个手指的多点触摸,这种多个手指间的互动使得开发者在处理多点触摸时面临了很大的挑战,在Silverlight框架中,触摸输入是通过事件来获取的。

  Silverlight支持两种不同的编程接口来支持多点触摸,分别为:底层接口和高层接口。其中,

  底层接口:是基于静态的Touch.FrameReported事件;

  高层接口:是由UIElement类中定义3个事件组成,这些事件统称为:Manipulation事件

1.底层接口

  Silverlight底层触摸接口的核心是:TouchPoint类型,TouchPoint的每个实例分别表示触摸屏幕的一个特定手势。

TouchPoint具有四个只读属性:

属性 类型 说明
Action TouchAction 枚举类型,包含Down、Move、Up三个成员
Position  Point 表示触摸坐标,相对于特定元素左上角的位置,称为参考(reference)元素。
Size Size 类型为Size,表示接触面积(以及手指压力大小),但在Windows Phone中目前还没有作用。
TouchDevice TouchDevice

有两个只读属性:①.Id,类型为int,用于区分不同的手势,从Down到Up的所有事件中,一个特定的手势是由一个唯一的Id。

          ②.DirectlyOver,类型为UIElement,手指下的最顶层的元素,通常用来确定用户正在触摸的元素。

  下面让我们来观察一个示例,该示例的效果是:只要触摸屏幕内的任何元素,TextBlock元素的文本颜色就会随机改变:

首先在MainPage.xaml中增加一个TextBlock元素:

1  <TextBlock Name="txtblk" Text="Hello,Windows Phone!" Padding="0 34" HorizontalAlignment="Center" VerticalAlignment="Center"/>

要使用底层触摸接口需要为静态的Touch.FrameReported事件注册一个事件处理程序。

1  Touch.FrameReported += OnTouchFrameReported;//绑定事件

下面是OnTouchFrameReported方法的代码,该事件处理程序获取应用程序中所有的触摸事件(其中,"rand"变量是Random类的一个实例,随机生成RGB颜色)。

复制代码
1    private void OnTouchFrameReported(Object sender, TouchFrameEventArgs args)
2 {
3 TouchPoint primaryTouchPoint = args.GetPrimaryTouchPoint(null);//获取触屏点左上角的位置
4

5 if (primaryTouchPoint != null && primaryTouchPoint.Action == TouchAction.Down)//判断触控的类型
6 {

7 this.txtblk.Foreground = new SolidColorBrush(Color.FromArgb(255, (byte)rand.Next(256), (byte)rand.Next(256), (byte)rand.Next(256)));//随机改变TextBlock文本的颜色
8 }
9 }
复制代码

 

请注意这个方法是效果:即使我们点击TextBlock以外的区域,也同样会触发OnTouchFrameReported事件,这显然没有达到我们的预期,但是如何把事件的作用只限制在TextBlock控件中呢?很简单,只需要加一个If判断就可以了:

复制代码
 1   private void OnTouchFrameReported(Object sender, TouchFrameEventArgs args)
2 {
3 TouchPoint primaryTouchPoint = args.GetPrimaryTouchPoint(null);
4
5 if (primaryTouchPoint != null && primaryTouchPoint.Action == TouchAction.Down)//判断触控的类型
6 {
7 if (primaryTouchPoint.TouchDevice.DirectlyOver == this.txtblk)//获取触控的最顶层元素
8 {
9 this.txtblk.Foreground = new SolidColorBrush(Color.FromArgb(255, (byte)rand.Next(256), (byte)rand.Next(256), (byte)rand.Next(256)));
10 }
11 }
12 }
复制代码

这样,就除了触摸TextBlock元素以外都不会触发该事件了。运行如下:

2.高层接口

  Silverlight中的高层接口包含了3个事件:ManipulationStarted  ManipulationDelta  ManipulationCompleted。这些事件并不处理单个的手势活动,而是将多个手势的活动合并到转换和缩放中。这些事件也累加了速度信息,可以用来实现惯性操作。

高层接口和底层接口的区别在于:

  Touch.FrameReported为整个应用程序传递触摸信息,而Manipulation事件是基于单个元素的。

 下面让我们来查看一个示例程序:

这是MainPage.xaml代码,我们直接在xaml中注册事件:

1   <TextBlock Text="Hello Windows Phone" Padding="0 34" HorizontalAlignment="Center" VerticalAlignment="Center" ManipulationStarted="TextBlock_ManipulationStarted"/>
2 </Grid>

 

MainPage.xmal.cs中的事件处理程序:

复制代码
 1   public partial class MainPage : PhoneApplicationPage
2 {
3 // 构造函数
4 Random rand = new Random();
5 public MainPage()
6 {
7 InitializeComponent();
8 }
9
10 private void TextBlock_ManipulationStarted(object sender, ManipulationStartedEventArgs e)
11 {
12 TextBlock txtblk = sender as TextBlock;
13 Color clr = Color.FromArgb(255, (byte)rand.Next(256), (byte)rand.Next(256), (byte)rand.Next(256));
14
15 txtblk.Foreground = new SolidColorBrush(clr);
16 e.Complete();//不是必须的,表示已经完成了操作
17 }
18 }
复制代码

在这个事件处理程序中,只有触摸了TextBlock控件,才会触发这个事件。

换一种方式能够实现同样类似的效果,而且更简单 —— UIElement类定义了所有的Manipulation事件,而Control(MainPage的基类)为这些事件提供了protected的虚方法,现在并不需要为MainPage页面注册Manipulation事件的处理程序,只需要重写这个虚方法就可以了。

参考下面的示例:

MainPage.xmal

<TextBlock Name="txtblk" Padding="0 34" VerticalAlignment="Center" HorizontalAlignment="Center" Text="Hello,Windows Phone"/>

MainPage.xmal.cs

复制代码
 1  public partial class MainPage : PhoneApplicationPage
2 {
3 Random rand = new Random();
4 Brush originalBrush;
5 // 构造函数
6 public MainPage()
7 {
8 InitializeComponent();
9 originalBrush = this.txtblk.Foreground;
10 }
11
12 protected override void OnManipulationStarted(ManipulationStartedEventArgs e)
13 {
14 if (e.OriginalSource == this.txtblk)
15 {
16 this.txtblk.Foreground = new SolidColorBrush(Color.FromArgb(255, (byte)rand.Next(256), (byte)rand.Next(256), (byte)rand.Next(256)));
17 }
18 else
19 {
20 this.txtblk.Foreground = originalBrush;
21 }
22
23 e.Complete();
24 base.OnManipulationStarted(e);
25 }
26 }
复制代码

在上面的示例中我们可以通过OriginalSource属性知道事件在可视化树中的真实来源,也就是实际触发事件的元素。这得益于Sliverlight的一个功能特征路由事件处理(routed event handling).

3.路由事件

  如果顶层元素不关心一个事件的话,该事件就会转发到该元素的父元素去,这样,一直转发到可视化树最高级的PhoneApplicationFrame元素为止,沿途的任何元素都可以获取这个输入事件并进行处理,也能阻止事件往树的高层继续传递。

  那么根据上面的原理我们编写一个新的示例,注册一个Manipulation事件和重写Manipulation事件的虚方法,前者只处理TextBlock的触摸事件,后者负责处理MainPage页面上的所有触摸事件。

MainPage.xmal:

  <TextBlock Name="txtblk" Text="Hello,Windows Phone" Padding="0 34" FontSize="28" VerticalAlignment="Center" HorizontalAlignment="Center" ManipulationStarted="txtblk_ManipulationStarted"/>

MainPage.xmal.cs:

复制代码
 1   public partial class MainPage : PhoneApplicationPage
2 {
3 Random rand = new Random();
4 Brush originalBrush;
5 // 构造函数
6 public MainPage()
7 {
8 InitializeComponent();
9 originalBrush = this.txtblk.Foreground;
10 }
11
12 private void txtblk_ManipulationStarted(object sender, ManipulationStartedEventArgs e)
13 {
14 this.txtblk.Foreground = new SolidColorBrush(Color.FromArgb(255,(byte)rand.Next(256),(byte)rand.Next(256),(byte)rand.Next(256)));
15 e.Complete();
16 e.Handled = true;//表示事件已经处理,不需要再进一步传递到可视化树的上层了
17 }
18
19 protected override void OnManipulationStarted(ManipulationStartedEventArgs e)
20 {
21 this.txtblk.Foreground = originalBrush;
22
23 e.Complete();
24 base.OnManipulationStarted(e);
25 }
26 }
复制代码

程序运行效果:

 触摸TextBlock随机改变文本颜色         触摸TextBlock以外的区域TextBlock文本颜色将回复到初始状态

   

参考资料:

  http://msdn.microsoft.com/zh-cn/library/cc189018(v=vs.95).aspx

  《Programming Windows Phone 7 Microsoft Silverlight Edition》

作者:晴天猪

出处:http://www.cnblogs.com/IPrograming

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

原文地址:https://www.cnblogs.com/zhanghaifeng/p/2480907.html