编辑:为避免混淆:这是关于以前称为或仍称为 Microsoft Surface 1.0 的表。不是以前叫微软Surface 2.0的 table ,也不是现在叫微软Surface的平板电脑。 编辑结束
我正在编写一个 WPF 应用程序,它应该可以在桌面系统以及 MS Surface/PixelSense 1.0 上运行。 我正在寻找关于通常如何完成的约定。
我知道平台之间存在一些差异,这就是为什么桌面版和 PixelSense 版本的基本 GUI 骨架不同的原因(在这种情况下,桌面版中的 Canvas
和 PixelSense 版中的 ScatterView
为根 GUI 元素)。
但是,桌面版本中有许多基于 WPF 的用户控件/GUI 片段,它们在 PixelSense 版本中的显示方式应该或多或少相同。
不幸的是,标准 WPF 控件似乎在 PixelSense 中不起作用。 控件如 CheckBox
必须替换为 SurfaceCheckBox
为了对用户输入使用react,可以通过 PixelSense 上的这个小代码示例轻松验证:
var item = new ScatterViewItem();
var sp = new StackPanel();
item.Content = sp;
item.Padding = new Thickness(20);
sp.Children.Add(new CheckBox() { Content = "CheckBox" });
sp.Children.Add(new SurfaceCheckBox() { Content = "SurfaceCheckBox" });
myScatterView.Items.Add(item);
显然,这意味着 WPF 用户控件无法在没有任何更改的情况下显示在 PixelSense 上,正如 Microsoft's documentation on the PixelSense presentation layer 等资源中的声明所证实的那样。 , SO 问题 such as this one related to a WPF tree view另请参阅,this blogpost on the PixelSense WPF layer或 this SO question on how to rewrite a WPF desktop application for PixelSense .后一个页面甚至将所需的更改称为最小,但它们仍然是更改。
此外,对 this SO question on how to use a particular WPF desktop control on PixelSense 的 react 暗示使用 .NET 4.0 可能会简化事情,但我认为 PixelSense 不支持 .NET 4.0 1.0 SDK(据我所知,它是基于 .NET 3.5 的)。
作为一名软件工程师,我仍然不同意使用相同的编程语言两次编写相同的 GUI 片段(由相同布局中的基本相同控件和对数据模型的相同行为组成)的策略。这似乎是错误的。
因此,到目前为止我发现了三种可能的解决方案:
Surface*
同行。 缺点:我目前倾向于第三种选择,因为它似乎是为独立于平台而付出的可接受的代价。然而,我认为 WPF 作为桌面和 PixelSense GUI 之间的连接元素,这应该是一个常见的问题,我想知道这是否以前没有解决过。所以,我在这里问:这通常是如何完成的?
P.S.:方向不是问题。上述 GUI 片段显示在 PixelSense 上的可旋转 ScatterViewItems 中,并在桌面上以其正常的垂直方向显示。
最佳答案
让我们从回到 Surface 1.0 正在构建的时代开始……
那一年是2006年,Windows操作系统(甚至主流手机!)中还没有多点触控的概念。没有允许应用程序响应同时与多个控件交互的用户的 API。现有 UI 框架中内置的输入路由、捕获和聚焦机制基本上都禁止多点触控以非蹩脚的方式工作。即使这些问题神奇地消失了,当用户做了一些他们无法处理的事情(例如同时单击“保存”和“退出”按钮)时,大多数应用程序仍然会崩溃,并且用户会非常暴躁,因为外观和现有应用程序/控件的感觉针对微小的鼠标光标而不是粗大的手指进行了优化。
所以,在 2006 年,我必须带领 Surface 团队在 WPF 之上创建一个抽象层来解决所有这些问题……结果就是你要问的 1.0 SDK。我们试图通过对现有 UI 控件进行子类化而不是创建全新的层次结构来最小化您提到的软件工程问题(这个决定使开发 SDK 变得更加困难顺便说一句),因此虽然您必须在每个平台上使用实例化不同的类,但之后控件的原始版本中使用的事件和属性将按预期在 Surface 版本中工作。
快进到 2009 年……多点触控开始流行起来。 Windows 7 添加了对多点触控的原生支持,但并未真正解决 UI 框架问题。
快进到 2010 年……WPF 和 Surface 团队合作采用 Surface 为我列出的问题构建的许多解决方案,使它们适应 Win7 的 native 触摸堆栈,并将它们作为内置于 WPF 4.0 的一部分发布。 .. 这提供了多点触控输入路由、事件、捕获和焦点,但不能简单地将触控功能添加到内置的 WPF 控件中而不破坏大量现有应用程序。因此,Surface 团队发布了“Surface Toolkit for Windows Touch”,它提供了大多数 Surface 1.0 UI 控件的 WPF 4.0 兼容版本。但是 2006 年的 Surface 1.0 与这个新版本的 WPF 不兼容,因此虽然您最终可以为 Windows 和 Surface 构建杀手级触控体验,但您仍然无法 100% 共享您的代码。
快进到 2011 年... Surface 2.0(使用 PixelSense 技术的)发布。它使用新的 WPF 4.0 功能(不再需要 Surface 1 SDK 附带的许多 API)并且包括本质上是 Surface Toolkit for Windows 的更新版本,尽管现在控件已重新设计为地铁。最后,产品时间线已经同步,您可以使用单一代码库为两个平台构建出色的触控体验。
好的,现在回到你现在的问题……你问的是 Surface 1.0,所以 2011 年的精彩并没有真正帮助你。不过,您可以利用 2010 年的东西:
视窗触控
通过 WPF 4 的输入堆栈路由它(执行此操作的能力不是
非常广为人知,但它是专门为这种类型的
设想)。
那么你如何做这些事情呢?好问题。幸运的是,我的好友 Joshua Blake 有一篇博客文章以及一些可重用的代码来引导您完成它。看看http://nui.joshland.org/2010/07/sharing-binaries-between-surface-and.html .
关于c# - 在桌面和 Surface (PixelSense) 1.0 上运行的 WPF 应用程序的约定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11257909/