65.9K
CodeProject 正在变化。 阅读更多。
Home

Silverlight 实验性技巧 (SLEX) - Silverlight 的 EventTrigger、PropertyTrigger、ReactiveTrigger、InvokeMethodAction、StoryBoardAction 等

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.81/5 (8投票s)

2010年1月4日

CPOL

6分钟阅读

viewsIcon

42419

downloadIcon

258

一套 Silverlight 实验性技巧(1)EventTrigger 和 PropertyTrigger 的自定义实现(2)在 MVVM 中调用视图模型中的方法(3)有条件地调用触发器和行为(4)用于导出自定义事件的 ReactiveTrigger。

Slex 中有什么?

如果您熟悉 Silverlight/Expression Blend,您应该知道 System.Windows.Interactions 框架,它提供了各种行为 (Behaviors)、触发器 (Triggers) 和动作 (Actions)。

如果您想回顾一下,请阅读这些文章

  1. 行为和触发器简介
  2. Silverlight 中的行为和触发器

好消息!!: 最近,我将 Slex 的大部分功能移植到了 WPF,名为 WEX,即 WPF Experimental Hacks。 在此 CodeProject 上查看。 Slex 的源代码是 Silverlight 4.0/VS2010,因为依赖对象绑定,而 Wex 是 .NET 3.5/VS2008

Slex 是在 System.Windows.Interactions 之上对一些附加触发器和动作的实验性实现,并包含一些扩展点。(您可能还会注意到 Expression Blend 已经为您提供了一些触发器和动作;我将在本文的结尾讨论 Slex 与它们的关联。)

如果您有兴趣学习如何为 Silverlight 实现自己的触发器、动作等,Slex 可以为您提供帮助,并带来一些有趣的实验(我最喜欢的是 ReactiveTrigger)。

在我们探索 Slex 的内容之前,先来看看它的功能。这是演示应用程序的截图

image

Slex 中的触发器和其中的动作可以基于条件进行调用

image

以下是 Slex 中一些值得注意的方面,它们在 Expression Blend 提供的触发器和动作中不可用。

  • Slex 允许您为触发器的调用定义多个条件(例如,您可以指定一个 KeyDown 事件触发器仅在按下“A”键时触发)
  • 您可以为触发器中的每个动作的调用指定多个条件
  • Slex 引入了一些新的触发器和动作,您将很快看到它们

目前,Slex Preview 2 提供了以下触发器

  • EventTrigger – 当事件被引发时触发。可以监听元素的事件,或 ViewModel 的事件。
  • PropertyTrigger – 当指定属性更改时触发。可以监听元素的属性,或 ViewModel 中的属性。
  • ReactiveTrigger – 可以“导入”您使用 MEF“导出”的可观察对象 (Observable)。适用于使用 System.Reactive 定义和使用自定义事件。

以及以下动作

  • InvokeMethodAction – 直接在 ViewModel 中或为目标元素调用方法,支持通过 XAML 传递参数
  • InvokeCommandAction – 调用 ViewModel 中的 ICommand
  • StoryBoardAction – 启动、停止、暂停、恢复或反转故事板
  • PropertyAction – 设置属性值(目前非常粗糙)

您可以为触发器和/或动作指定一个或多个 InvokingCondition。此外,InvokeMethodActionInvokeCommandAction 等动作具有 ActionParameters 属性,因此您可以在调用方法和命令时传递一个或多个参数。

有条件地调用触发器和动作

让我们看一个简单的场景示例 – 您需要在按下按钮时启动一个故事板,但前提是某个复选框已选中。假设您的 ButtonbtnBegin,您的 StoryBoardmyStoryBoard,您的 CheckBoxchkMain,您可以这样做(请参阅 StoryBoardAction 演示)

image

如果您查看上面的代码,您可能会发现我们为触发器本身指定了各种条件 – 只有当所有调用条件都为 True 时,触发器中的所有动作才会触发。您应该可以将 Expression Blend 附带的其他动作(您自己的自定义动作等)放置在 EventTriggerPropertyTriggerReactiveTrigger 中,以有条件地执行它们。

此外,您可能需要为触发器中每个动作的单独调用指定条件。您也可以做到这一点。例如,以下 Property Trigger 将仅在 txtData 文本框的 Text 属性为 Hello 且 myCheckBox 复选框被选中时执行。

image

更好的 MVVM - 调用 ViewModel 中的方法和命令并传递参数

请查看 InvokeMethodActionInvokeCommandAction(请参阅演示)。这些动作在 Preview 1 中有一些更改。

InvokeCommandAction 允许您调用 ViewModel 中的方法。假设您有一个名为 userList 的列表框——这里有一个简单的例子,说明如何在选择更改时执行命令,并且您可以为 ICommand 指定一个参数,使用 ActionParameter。事实上,您可以传递多个 ActionParameter,在这种情况下,它们将作为对象数组传递给命令中的 CanExecuteExecute 方法。

image

这里还有更有趣的东西 - InvokeMethodAction。您可以使用 InvokeMethodAction 直接调用 ViewModel 中的方法。假设您有一个包含两个文本框和一个按钮的用户界面,并且您的 ViewModel 中有一个名为 Add 的方法,该方法接受两个 int 类型的参数。当用户点击 btnName 按钮时,您需要这样做来调用您的 Add 方法。

image

ReactiveTrigger – 通过 MEF 和 System.Reactive 解耦触发器

此预览版的一个有趣补充是 ReactiveTriggerReactiveTrigger 允许您导入您从其他地方导出的可观察对象 (Observable)。这将使您能够快速创建自定义用户输入触发器。我不会深入探讨实现细节,但假设您已经对 MEF 概念System.Reactive 概念 有所了解;这是您可以做到的(请参阅 Slex.Lib.Demo 中的 ReactiveTrigger 演示以获取完整的源代码)。

步骤 1 – 在您的宿主应用程序的某个位置,创建一个触发器并导出它

您的导出方法应匹配签名 Func<object,IObservable<EventResult>>。您可以使用 Slex.Lib 中的 ObservableExport 属性将您的触发器标记为可导出部分。此外,您在 ExportName 属性中提供的名称稍后将在 XAML 中用于“导入”此触发器。

image

步骤 2 – 在您的应用程序启动时,调用 SlexPartComposer 中的 Compose 方法,并传递您的目录

在这种情况下,我只是传递一个包含当前程序集的程序集目录,因为我的触发器是宿主应用程序的一部分。并且,我在 App.xaml.cs 构造函数中添加了这一行。

image

步骤 3 – 只需在 XAML 中使用触发器

好了,您就可以导入导出的触发器了,当按下按键时,它就会被触发。

image

将 Slex 与 Blend 结合使用

您应该能够使用 Blend 修改大多数 Slex 触发器和动作。例如,让我们看看上面的 Event Trigger 和相关的动作参数在 Blend 中会是什么样子。您可能会发现您可以在 Blend 中修改触发器的条件和参数(嗯,更确切地说,它们是 AttachableCollections :))。

image

Slex 与 Expression Blend 附带的行为、触发器和动作有何关系?

如前所述,Slex 构建在 System.Windows.Interactions 框架之上,您将能够混合搭配现有的 Expression Blend 行为、触发器和动作以及 Slex 触发器和动作。

存在一些重叠的领域——例如,Slex 对某些触发器(如 EventTrigger)有自己的实现,与 Blend 的 EventTrigger 相比,它提供了一些“额外”的特性。

What Next?

如前所述,这是一组实验性技巧,用于推广一些想法。还有一些想法正在进行中,当我有时间时,将在未来实现。

如果您有兴趣共同开发,请发送电子邮件至 amazedsaint (at) gmail (dot) com。

另外,请在 Twitter 上关注我 @amazedsaint

© . All rights reserved.