DataTrigger
这个触发器允许我们基于数据的变化来改变属性值。我们可以将它绑定到(或者理解为让它观察)某个依赖属性,或者视图模型中的某个具有通知功能的属性上。这样当属性值变化时,触发器就会生效。
WPF 自带的 DataTrigger
首先我们快速回忆一下 WPF 自带的 DataTrigger
的使用方式。假设我们有一个视图模型 MyViewModel
,它有一个布尔属性 IsActive
,我们希望当这个属性为 True
时,按钮的背景颜色变为绿色,否则为红色。我们可以这样做:
提示
除了 Style
和 Template
,控件本身也包含一个 Triggers
集合。但是控件的只能包含 EventTrigger
,不能包含 Trigger
、DataTrigger
等。
行为库的 DataTrigger
现在我们来看一下行为库的 DataTrigger
。下面是一个简单的例子,目的是实现与上面类似的功能:
乍一看会觉得它与 WPF 自带的 DataTrigger
没有什么区别,但实际上区别还是有的:
- 行为库的
DataTrigger
只能放在Interaction.Triggers
中,而不能放在Style
或Template
中。它与 WPF 原生的DataTrigger
完全是两回事,只不过名字相同。 - 行为库的
DataTrigger
所实现的效果是“生硬”的,也就是它在条件满足时,会采用类似于在后台代码中直接修改控件属性值的方式来实现效果,但这是有代价的:这样的修改拥有极高的优先级,会轻易覆盖掉来自Style
、Template
等的设置。 - 行为库的
DataTrigger
在满足条件并触发动作后,即便后续条件不再满足,之前的动作也不会被撤销。也就是说,DataTrigger
只会在条件满足时执行一次动作,而不会在条件不满足时执行相反的动作。因此在上面的例子中我们需要写一对DataTrigger
来分别处理True
和False
的情况,从而让效果变得可逆;WPF 自带的DataTrigger
则不需要这样做,因为它会自动处理条件不满足时的情况。 - 行为库的
DataTrigger
除了除了与 WPF 原生的提供了相同到Binding
和Value
属性外,还额外提供了Comparison
属性,允许我们指定更多的比较方式,比如NotEqual
、GreaterThan
、LessThan
等等,从而让触发条件变得更加灵活。
基于上面的第 4 条,我们可以将上面例子中的第二个 DataTrigger
改为使用 NotEqual
,从而简化代码:
提示
或许对于 True
、False
这种天然拥有互斥关系的值来说,使用 NotEqual
并没有太大意义;但对于其他类型的值来说,NotEqual
就显得非常有用了。比如我们想判断某个属性与 null
的关系,那么在没有 NotEqual
的情况下,可能就会比较无力了。