每次去纽约的美国自然历史博物馆,我必定会好好参观一下灵长类馆。灵长类馆选择了大量的骨骼和剥制标本,展示了一幅灵长类动物进化的全景,动物从极小的树鼩、狐猴和绒猴一直到黑猩猩、大猩猩和人类。
这个展览最引人注目的是所有灵长类动物都有着惊人的共性:手的骨骼结构相同,包括一个对生拇指。这种使我们的祖先和远亲可以抓握从而爬上树枝的相同关节排列和数目,让我们的物种可以影响周围的世界和从事建造工作。我们的双手可能源于数百万年前小型灵长类动物的爪子,而双手也是使我们真正成为人类的重要因素。
我们会本能地伸出手指指点甚至触摸计算机屏幕上的显示内容,又有什么奇怪呢?
为了满足人类希望使手指与计算机更密切相融的愿望,我们的输入设备也一直在不断发展。鼠标对于选择和拖动操作游刃有余,但对于形态自由的素描和手写操作却无法胜任。我们可以用 Tablet 笔针流畅书写,但在拉伸或移动时却倍感困难。我们从 ATM 和博物馆售票处熟悉了触摸屏,但通常仅限于简单的点和按操作。
我认为称为“多点触控”的这项技术代表了一个巨大的飞跃。顾名思义,多点触控可以检测到多个手指,超越了过去的触摸屏概念,在通过屏幕可传达的移动和手势类型方面,产生了巨大差异。多点触控已经从过去的触摸式输入设备发展到一个新阶段,但同时,在本质上这是与以前不同的输入模式。
多点触控最明显的应用可能是在电视新闻节目中,大屏幕上显示一些地图供其气象预报员或专家操作。Microsoft 已在几个方面研究多点触控(从咖啡桌大小的 Microsoft Surface 计算机到 Zune HD 之类的小型设备),并且这项技术已完全成为智能手机上的标准。
尽管 Microsoft Surface 可同时响应多个手指(甚至包括数台内部照相机来查看玻璃上放置的物体),其他大多数多点触控设备仅限于离散的数。许多设备只能响应两个手指(即所谓的触摸点)。(我将把手指和触摸点作为同义词汇使用。)但协作效应发挥着作用:在计算机屏幕上,两个手指的作用大于一个手指的两倍作用。
两个触摸点的限制是多点触控显示器的特征,这种显示器最近已经可用于桌面 PC 和便携式计算机,以及去年 11 月在 Microsoft 专业开发人员会议 (PDC) 上向与会者发布的定制 Acer Aspire 1420P 便携式计算机(通常称为 PDC 便携式计算机)。PDC 便携式计算机的发布为成千上万的开发人员提供了一个难得的机会来编写多点触控感知应用程序。
我以前使用 PDC 便携式计算机探索 Silverlight 3 下的多点触控支持。
Silverlight 事件和类
多点触控支持正成为各种 Windows API 和框架中的标准。这种支持已内置到 Windows 7 和即将发布的 Windows Presentation Foundation (WPF) 4 中。(Microsoft Surface 计算机也基于 WPF,但包括了一些自定义扩展以实现其非常特殊的一些功能。)
在本文中,我准备重点介绍 Silverlight 3 中的多点触控支持。该支持稍有不足,但肯定已经够用,在探讨基本的多点触控概念时非常有用。
如果您将一个多点触控 Silverlight 应用程序发布到您的网站,谁能够使用它?用户将需要一个多点触控显示器,当然还需要在支持多点触控的操作系统和浏览器下运行 Silverlight 应用程序。目前,在 Windows 7 下运行的 Internet Explorer 8 提供这种支持,将来可能会有更多的操作系统和浏览器支持多点触控。
Silverlight 3 对多点触控的支持由 5 个类、1 个委派、1 个枚举和 1 个单一事件组成。您的 Silverlight 程序是否在多点触控设备上运行,如果是,该设备支持多少个触摸点,这些是无法确定的。
一个需要响应多点触控的 Silverlight 应用程序必须将一个处理程序连接到静态 Touch.FrameReported 事件:
Touch.FrameReported += OnTouchFrameReported;
您可以在未配备多点触控显示器的计算机上连接此事件处理程序,而不会出现问题。FrameReported 事件是静态 Touch 类的唯一公共成员。处理程序如下所示:
void OnTouchFrameReported(
object sender, TouchFrameEventArgs args) {
...
}
您可以在应用程序中安装多个 Touch.FrameReported 事件处理程序,所有这些事件处理程序都会报告应用程序中任何位置的所有触控事件。
TouchFrameEventArgs 有一个名为 TimeStamp 的公共属性(我还没有机会使用)和三个重要的公共方法:
TouchPoint GetPrimaryTouchPoint(UIElement relativeTo)
TouchPointCollection GetTouchPoints(UIElement relativeTo)
void SuspendMousePromotionUntilTouchUp()
GetPrimaryTouchPoint 或 GetTouchPoints 的参数仅用于报告 TouchPoint 对象的位置信息。您可以将空值用于此参数,位置信息相对于整个 Silverlight 应用程序的左上角。