操作基础知识
操作定义为一根或多根手指触控特定元素的动作。完整的操作从 ManipulationStarting 事件开始,紧接着是 ManipulationStarted,并最终以 ManipulationCompleted 结束。中间可能有多个 ManipulationDelta 事件。
每个操作事件都附带有其自己的事件参数集,该参数集封装在一个根据该事件命名并附加了 EventArgs 的类中,例如,ManipulationStartingEventArgs 和 ManipulationDeltaEventArgs。这些类从我们熟悉的 InputEventArgs 派生,而后者又从 RoutedEventArgs 派生。这些类包括指示事件来源的 Source 和 OriginalSource 属性。
在 SimpleManipulationDemo 程序中,Source 和 OriginalSource 均设置为生成操作事件的 Image 元素。只有 IsManipulationEnabled 属性设置为 true 的元素才会在这些操作事件中显示为 Source 和 OriginalSource 属性。
此外,与操作事件相关联的每个事件参数类都包括一个名为 ManipulationContainer 的属性。这是发生多点触控操作的元素。操作事件中的所有坐标都相对于此容器。
默认情况下,ManipulationContainer 属性设置为与 Source 和 OriginalSource 属性相同的元素,也就是被操作的元素,不过这可能不是您所希望的。通常,大家不希望操作容器与被操作的元素相同,因为动态移动、缩放和旋转报告触控信息的同一元素需要技巧性很强的交互。您应将操作容器作为被操作元素的父项,或者作为沿可视化树向上追寻的某个元素。
在大多数操作事件中,ManipulationContainer 属性都是只读属性。但元素接收的第一个操作事件例外。在 ManipulationStarting 中,您可以将 ManipulationContainer 更改为更适合的容器。在 SimpleManipulationDemo 项目中,此工作只需通过一行代码即可完成:
args.ManipulationContainer = this;
在所有后续事件中,ManipulationContainer 将是 MainWindow 元素,而不是 Image 元素,并且所有坐标都将相对于该窗口。由于包含 Image 元素的 Grid 也与该窗口对齐,因此,此方法非常适用。
OnManipulationStarting 方法的其余部分通过重置该 Grid 中所有 Image 元素的 Panel.ZIndex 附加属性,专门用于在前台显示触控 Image 元素。这是处理 ZIndex 的一种简单方法,但可能不是最好方法,因为它会发生突然变化。
ManipulationDelta 和 DeltaManipulation
SimpleManpulationDemo 处理的另一个唯一事件是 ManipulationDelta。ManipulationDeltaEventArgs 类定义 ManipulationDelta 类型的两个属性。(是的,该事件和类具有相同的名称。)这些属性是 DeltaManipulation 和 CumulativeManipulation。顾名思义,DeltaManipulation 反映了自上一个 ManipulationDelta 事件以来发生的操作,CumulativeManipulation 表示从 ManipulationStarting 事件开始的完整操作。
ManipulationDelta 具有四个属性:
Translation 属性,类型为 Vector
Scale 属性,类型为 Vector
Expansion 属性,类型为 Vector
Rotation 属性,类型为 double
Vector 结构定义 double 类型的两个属性,分别名为 X 和 Y。Silverlight for Windows Phone 7 中的操作支持的一个较显著的差异是缺少 Expansion 和 Rotation 属性。
Translation 属性指示水平方向和垂直方向的移动(或平移)。对元素的单指操作可生成平移变化,但平移也可以是其他操作的一部分。
Scale 和 Expansion 属性均指示大小变化(缩放),这始终需要两根手指。Scale 依据乘法进行缩放,Expansion 依据加法进行缩放。使用 Scale 可设置缩放转换;使用 Expansion 可按照与设备无关的单位增大或减小某个元素的 Width 和 Height 属性。