7

我目前正在分析一些使用广泛使用MultiDataTriggers的样式的 XAML (每种样式有 8-10 个多数据触发器,每个触发器有 4-6 个条件)。在查看此内容时,我正在考虑使用转换器或多值转换器)是否更有效,尤其是在无法调试 MultiDataTriggers 的情况下。

谁能权威地说明 MultiDataTriggers 是如何编译的?我知道条件是 ANDed在一起的,这是否是以捷径为特色的方式编译的?

多个 MultiDataTriggers 呢?它们是否短路以使第一个完全满足导致评估停止?或者如果有几个都满意,他们都评价为最后一个获胜?

4

2 回答 2

9

Triggers are evaluated from top to bottom. 它适用于所有类型的触发器(Trigger、DataTrigger、MultiTrigger 和 MutliDataTrigger)。

多个 MultiDataTriggers 呢?它们是否短路以使第一个完全满足导致评估停止?或者如果有几个都满意,他们都评价为最后一个获胜?

如前所述,触发器是从上到下评估的。因此,如果第一个满足所有条件并不意味着不会评估进一步的触发器。评估应用于更改属性的所有触发器,如果​​它们中的任何两个在触发器内设置相同的属性,则last trigger always wonoverrides the property set by first trigger

<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>

Test2IsEnable评估结果为真时,文本将始终存在。


谁能权威地说明 MultiDataTriggers 是如何编译的?我知道条件是 ANDed 在一起的,这是否是以捷径为特色的方式编译的?

是的,MultiDataTrigger 中具有捷径功能,即 if first condition evaluate to be false, second condition won't be checked. 此示例验证了这一点 -

<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>

在这两种情况下都应用了转换器,但如果IsEnabledfalseconverter gets hit only once因为第一个条件评估为假。但万一IsEnabledtrueconverter gets hit twice因为第一个条件成功满足。

于 2013-11-10T11:27:10.707 回答
2

转换器允许调试和更复杂的逻辑,但它们还必须检查所有的逻辑Bindings并在每次Bindings更改时调用外部函数。所以它们几乎在所有情况下都比触发器慢。触发器在第一个未满足条件处停止。

所以我的回答是尽可能多地使用 MutiDataTrigger,当你需要更多逻辑时,取决于是否有可能在其他地方重复某些条件,你可以选择实现一个额外的DependencyProperty(当其他一些属性发生变化时它会改变) 或使用转换器。

例如,我有 5 个要绑定的属性:

IsChecked = A && B && (C || D || !E)
IsReadonly = !A && !B && (C || D || !E)

所以我会创建一个新属性 F 等于C || D || !E并且当这三个更改之一发生更改时, update F。现在我可以F用作第三个触发器绑定路径。

于 2013-11-10T11:40:44.583 回答