(多个)MultiDataTrigger 与转换器的效率

Posted

技术标签:

【中文标题】(多个)MultiDataTrigger 与转换器的效率【英文标题】:Efficiency of (multiple) MultiDataTrigger vs. Converter 【发布时间】:2013-11-22 05:30:21 【问题描述】:

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

谁能权威地说明 MultiDataTriggers 是如何编译的?我了解Conditions are ANDed一起,这是编译成短截的特色吗?

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

【问题讨论】:

【参考方案1】:

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

多个 MultiDataTrigger 怎么样?它们是否短路了 第一个完全满足导致评估停止?或者是 如果几个满意,他们都评价最后一个获胜?

如上所述,触发器是从上到下评估的。因此,如果第一个满足所有条件并不意味着不会评估进一步的触发器。评估应用于更改属性的所有触发器,如果​​其中任何两个在触发器内设置相同的属性,则 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>

IsEnable 评估为真时,文本将始终为Test2


谁能权威地说明 MultiDataTriggers 是如何编译的?一世 了解条件是与在一起的,这是编译在 这样的捷径有特色吗?

是的,MultiDataTrigger 中具有捷径功能,即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 因为第一个条件成功满足。

【讨论】:

谢谢,很好的答案。像这样的例子和 MSDN 的链接一样好:)【参考方案2】:

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

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

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

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

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

【讨论】:

感谢您的回答,我不确定您是否理解我所问内容的全部含义? @Rohits 的回答表明我必须改用转换器,因为 a)这些多数据触发器位于已经非常缓慢的网格上; b)多数据触发器增加了绑定错误的风险,并且 c)我想避免复杂的属性,因为绑定的对象已经有足够的这些属性,并且由于开发人员的编码不好,这些很容易变慢。如果我要使用复杂的属性,那么我不妨使用专门为该特定绑定量身定制的转换器。 但话虽如此,您的答案可能对使用有限数量的多数据触发器但希望简化其中条件的人有好处。

以上是关于(多个)MultiDataTrigger 与转换器的效率的主要内容,如果未能解决你的问题,请参考以下文章

MultiDataTrigger

关于MultiDataTrigger和MultiTrigger的一些注意事项

关于MultiDataTrigger和MultiTrigger的一些注意事项

WPF MultiDataTrigger AND 条件

关于MultiDataTrigger和MultiTrigger的一些注意事项

实体框架,如何将 IQueryable 与多个 where 转换为 SQL 一起使用?