在桌面和Surface(PixelSense)1.0上运行的WPF应用程序的约定

时间:2012-06-29 07:40:08

标签: c# .net wpf cross-platform pixelsense

编辑:为了避免混淆:这是关于之前调用的表,或者仍称为 Microsoft Surface 1.0 的表。它不是以前称为 Microsoft Surface 2.0 的表,而是与现在称为 Microsoft Surface 的平板电脑无关。 编辑结束

我正在编写一个WPF应用程序,该应用程序既可以在桌面系统上运行,也可以在MS Surface / PixelSense 1.0上运行。 我正在寻找关于通常如何做的约定。

我知道平台之间存在一些差异,这就是桌面和PixelSense版本的基本GUI骨架不同的原因(在这种情况下,桌面版本为Canvas且{{1}在PixelSense版本中作为根GUI元素)。

但是,桌面版中有许多基于WPF的用户控件/ GUI片段,它们在PixelSense版本中的显示方式大致相同。

不幸的是,标准WPF控件在PixelSense中似乎不起作用。 ScatterView之类的控件必须替换为CheckBox才能对用户输入作出反应,如可以使用PixelSense上的这个小代码示例轻松验证:

SurfaceCheckBox

显然,这意味着无法在没有任何更改的情况下在PixelSense上显示WPF用户控件,正如Microsoft's documentation on the PixelSense presentation layer等资源中的语句所证实的那样,问题such as this one related to a WPF tree view也引用了this blogpost on the PixelSense WPF layer,{{ 3}}或this SO question on how to rewrite a WPF desktop application for PixelSense。后一页甚至调用了所需的更改 minimal ,但仍然是更改。

此外,对this SO question on how to use a particular WPF desktop control on PixelSense的反应意味着使用.NET 4.0可能会简化事情,但我不认为PixelSense 1.0 SDK(它是.NET)支持.NET 4.0基于3.5,据我所知)。

作为一名软件工程师,我仍然不同意使用相同的编程语言两次编写相同GUI片段(在相同布局中基本相同的控件,对数据模型具有相同行为)的策略。这似乎是错的。

所以,到目前为止我找到了三种可能的解决方案:

  • 为标准WPF编写GUI片段。然后使用脚本复制包含这些GUI片段的库,同时转换所有相关的Xaml文件(例如使用XSLT),以用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控件。
    缺点:< /强>
    • 每当WPF项目中的某些内容发生变化时,始终保持脚本正常工作并运行它们所需的维护工作量增加。
    • 此外,定义要考虑哪些Xaml文件以及使用哪些控件替换(考虑其他第三方PixelSense控件......)可能最终会变得复杂。
    • 最后,生成的PixelSense项目将是WPF项目的精确副本,除了Xaml文件,因此不能引入特定于PixelSense的代码(或者如果可以,这将生成用于生成PixelSense的脚本)项目更复杂)。
  • 仅定位PixelSense / Surface,让桌面用户安装Surface SDK。感谢用户Clemens提供建议!
    缺点:
    • 用户必须安装 Surface 1.0 SDK ,这在当前系统上是一项非常重要的操作:使 Surface 1.0 SDK 在Windows上运行7 64位机器,various actions such as patching MSI files必须执行。
    • PixelSense / Surface 1.0模拟器是在台式计算机上运行Surface 1.0应用程序的唯一可能性。这个模拟器不是很好用,并且在某些系统上是彻头彻尾的错误:在我的计算机上,它看起来像这样:buggy Surface 1.0 simulator(输出只覆盖了模拟器窗口的3/4,但是输入是在整个窗口。即点击Surface模拟的右下角,我必须点击进入模拟器窗口右下角(显然是透明的)。)
  • 创建GUI时,不要明确使用标准WPF或PixelSense控件类,而是使用特定于平台的工厂来创建适当的控件类型。
    缺点:
    • 不再使用Xaml编写GUI片段;至少大多数控件及其所有绑定都必须用C#代码创建。

我目前倾向于第三种选择,因为它似乎是一个可以接受的平台独立支付价格。然而,我认为WPF是桌面和PixelSense GUI之间的连接元素,这应该是一个常见的问题,我想知道这是否还没有解决过。所以,我在这里问:这通常是怎么做的?

P.S。:定位不是问题。上述GUI片段显示在PixelSense上的可旋转ScatterViewItems中,并在桌面上以垂直方向显示。

1 个答案:

答案 0 :(得分:7)

让我们首先在返回机器中跳跃到构建Surface 1.0的时候......

今年是2006年.Windows操作系统(甚至主流手机中)没有多点触控的概念!没有API允许应用程序在同时与多个控件交互时响应用户。内置于现有UI框架的输入路由,捕获和聚焦机制基本上都禁止多点触控以非糟糕的方式工作。即使这些问题神奇地消失了,大多数应用程序仍然会在用户做了一些他们不能处理的东西时崩溃(比如同时单击“保存”和“退出”按钮)并且用户会因为外观和放大器而非常暴躁;感觉现有的应用程序/控件针对微小的鼠标光标进行了优化,而不是大手指。

所以,在2006年,我领导Surface团队在WPF之上创建一个抽象层来解决所有这些问题......结果就是你要问的1.0 SDK。我们尝试通过子类化现有的UI控件而不是创建一个全新的层次结构来最小化您提到的软件工程问题(这个决定使得开发SDK 很多更难以btw),所以当你必须使用不同的实例化时每个平台上的类,但在此之后,控件的原始版本中使用的事件和属性将按预期的Surface版本工作。

快进到2009年......多点触控开始变得越来越活跃。 Windows 7增加了对多点触控的本机支持,但并未真正解决UI框架问题。

快进到2010年...... WPF和Surface团队合作采用Surface为我列出的问题构建的许多解决方案,使其适应Win7的原生触摸堆栈,并将它们作为内置部分运行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年的东西:

  1. 使用WPF 4 API和Surface Toolkit for构建您的应用 Windows Touch
  2. 编写一些采用Surface输入事件和代码的代码 通过WPF 4的输入堆栈路由它(执行此操作的能力不是 广为人知,但它是专门为这种类型而创建的 场景)。
  3. 那你怎么做那些事情?好问题。幸运的是,我的好友Joshua Blake有一篇博客文章以及一些可重复使用的代码来引导您完成它。看看http://nui.joshland.org/2010/07/sharing-binaries-between-surface-and.html