Silverlight支持两种不同的编程接口来支持多点触摸,可以简单地分类为底层接口和高层接口。其中底层接口是基于静态的Touch.FrameReported事件的。高层接口由UIElement类中定义的3个事件组成:ManipulationStarted,ManipulationDeta和ManipulationCompleted,这些事件统称为Manipulation事件,它把多个手指的交互操作合并成移动和缩放两个因子。下面分别从使用底层接口和高层接口两个方面进行总结。
使用底层触摸接口
要使用底层触摸接口,需要为静态的Touch.FrameReported事件注册一个事件处理程序。下面示例对此进行了演示,当单击TextBlock测试区域时,文本随机变成另一种颜色,当单击TextBlock测试区域以外区域时文本又变成原始的颜色。
XAML代码:
<Grid x:Name="LayoutRoot" Background="Transparent">
<TextBlock Name="txtblk"
Text="Hello,Windows Phone 7!"
Padding="0,34"
HorizontalAlignment="Center"
VerticalAlignment="Center"/>
</Grid>
C#代码:
public partial class MainPage : PhoneApplicationPage
{
Random rand = new Random();
Brush originalBrush;
// 构造函数
public MainPage()
{
InitializeComponent();
originalBrush = txtblk.Foreground;//获取txtblk的画刷,其中Foreground属性为Brush类型,默认值为SolidColorBrush,其Color值为 Black
Touch.FrameReported += OnTouchFrameReported;//注册事件处理程序
}
protected void OnTouchFrameReported(object sender, TouchFrameEventArgs e)
{
TouchPoint primaryTouchPoint = e.GetPrimaryTouchPoint(null);//调用TouchFrameEventArgs对象的方法,获取触摸点与屏幕左上角的相对位置
if (primaryTouchPoint != null && primaryTouchPoint.Action == TouchAction.Down)//Action为Down的主触控点
{
if (primaryTouchPoint.TouchDevice.DirectlyOver == txtblk)//手指触控的是最顶层元素
{
txtblk.Foreground = new SolidColorBrush(Color.FromArgb(255, (byte)rand.Next(256), (byte)rand.Next(256), (byte)rand.Next(256)));//指定一个随机颜色
}
else
{
txtblk.Foreground = originalBrush;//将txtblk的Foreground设回原始的画刷
}
}
}
}
效果如图:
单击TextBlock区域 单击TextBlock以外区域
使用高层触摸接口
Silverlight中的高层触摸接口包含了三个事件:ManipulationStarted,ManipulationDeta和ManipulationCompleted。Touch.FrameReported是为整个应用程序传递触摸信息的,而Manipulation事件是基于单个元素的,所以可以把ManipulationStarted事件处理程序注册到TextBlock上。下面示例使用高层触摸接口对前面的例子进行了重写。
XAML代码:
<Grid x:Name="LayoutRoot" Background="Transparent">
<TextBlock Name="txtblk"
Text="Hello,Windows Phone 7!"
Padding="0,34"
HorizontalAlignment="Center"
VerticalAlignment="Center"
ManipulationStarted="txtblk_ManipulationStarted"/>
</Grid>
C#代码:
public partial class MainPage : PhoneApplicationPage
{
Random rand = new Random();
Brush originalBrush;
// 构造函数
public MainPage()
{
InitializeComponent();
originalBrush = txtblk.Foreground;//获取原始画刷
}
private void txtblk_ManipulationStarted(object sender, ManipulationStartedEventArgs e)//处理注册事件处理程序
{
txtblk.Foreground = new SolidColorBrush(Color.FromArgb(255, (byte)rand.Next(256), (byte)rand.Next(256), (byte)rand.Next(256)));//指定一个随机颜色
e.Complete();//告诉系统不需要再处理该手指所涉及的Manipulation事件了
e.Handled = true;//表示该事件现已处理,不需要再进一步的传递到可视化树的上层了。涉及到路由事件的知识
}
protected override void OnManipulationStarted(ManipulationStartedEventArgs e)//重写基类虚方法
{
txtblk.Foreground = originalBrush;//设回原始的画刷
e.Complete();
base.OnManipulationStarted(e);//base关键字表示调用基类的方法
}
}
路由事件
Manipulation事件源自于用户触摸的可用顶层元素。但是如果该顶层元素不关心该事件的话,该事件会转发到该元素的父元素去,如此,一直转发到可视化树的最高级PhoneApplicationFrame元素为止。沿途的任何元素都可以获取这个输入事件并进行处理,也能阻止事件往树的高层继续传递。
这就是可以在MainPage中重写OnManipulationStarted方法使TextBlock得到Manipulation事件的原因。