多个MultiDataTriggers呢?它们是否被短路,以便第一个完全满足引起评估停止?还是它们都被评估,如果有几个满足,则最后一个获胜?
触发器从上到下进行评估
。这适用于所有类型的触发器(Trigger,DataTrigger,MultiTrigger和MutliDataTrigger)。
多个MultiDataTriggers呢?它们是否被短路,以便第一个完全满足导致评估停止?还是它们都被评估,并且如果有几个满足,则最后一个获胜?
正如所述,触发器从上到下进行评估。因此,如果第一个触发器满足所有条件,并不意味着进一步的触发器将不被评估。应用于更改属性的所有触发器都将被评估,并且如果其中任何两个触发器在触发器内设置相同的属性,则最后一个触发器总是获胜
并覆盖由第一个触发器设置的属性
。
<TextBlock>
<TextBlock.Style>
<Style TargetType="TextBlock">
<Style.Triggers>
<DataTrigger Binding="{Binding IsEnable}" Value="True">
<Setter Property="Text" Value="Test1"/>
</DataTrigger>
<DataTrigger Binding="{Binding IsEnable}" Value="True">
<Setter Property="Text" Value="Test2"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
当IsEnable
为真时,文本始终为Test2
。
有人可以权威地说明MultiDataTrigger是如何编译的吗?我明白条件是ANDed在一起的,这个过程是以短路方式编译的吗?
是的,在MultiDataTrigger中采用了短路的方式,即如果第一个条件的评估结果为假,则不会检查第二个条件
。这个示例验证了这一点 -
<TextBlock>
<TextBlock.Style>
<Style TargetType="TextBlock">
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsEnable,
Converter={StaticResource SingleValueConverter}}"
Value="True"/>
<Condition Binding="{Binding IsEnable,
Converter={StaticResource SingleValueConverter}}"
Value="True"/>
</MultiDataTrigger.Conditions>
<Setter Property="Text" Value="Test"/>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
在两种情况下都会应用转换器,但是如果 IsEnabled
是 false
,那么 转换器仅被触发一次
,因为第一个条件的结果为false。但是如果 IsEnabled
是 true
,那么 转换器被触发两次
,因为第一个条件成功地满足了。
转换器可以进行调试和更复杂的逻辑,但它们也必须检查它们的所有Bindings
并在每次Bindings
更改时调用外部函数。因此,在几乎所有情况下,它们比触发器慢。触发器会在第一个不满足条件的地方停止。
因此,我的建议是尽可能使用MutiDataTrigger,当需要更多逻辑时,根据是否可能在其他地方重复某些条件,您可以选择实现额外的DependencyProperty
(当一些其他属性更改时会发生变化),或使用转换器。
例如,我有5个属性要绑定:
IsChecked = A && B && (C || D || !E)
IsReadonly = !A && !B && (C || D || !E)
于是我创建了一个新属性F,等于C || D || !E
,当这三个中的一个发生变化时,更新F
。现在我可以将F
用作第三个触发器绑定路径。