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事件的原因。