多数据触发器 vs 多绑定数据触发器

39

我遇到了这样一种情况,在使用MultiDataTrigger或者使用带有MultiBindingDataTrigger的情况下,我可以轻松地实现相同的功能。是否有任何实质性的理由更喜欢其中一种方法而不是另一种方法?

使用MultiDataTrigger:

<MultiDataTrigger>
    <MultiDataTrigger.Conditions>
        <Condition Binding="{Binding Path=SomePath}" Value="SomeValue"/>
        <Condition Binding="{Binding Path=SomeOtherPath, Converter={StaticResource SomeConverter}}" Value="SomeOtherValue"/>
    </MultiDataTrigger.Conditions>
    <MultiDataTrigger.EnterActions>
        <BeginStoryboard Storyboard="{StaticResource MyStoryboard}"/>
    </MultiDataTrigger.EnterActions>
</MultiDataTrigger>

使用MultiBinding:

<DataTrigger Value="foo">
    <DataTrigger.Binding>
        <MultiBinding Converter="{StaticResource fooConv}"/>
            <Binding Path=SomePath/>
            <Binding Path=SomeOtherPath/>
        </MultiBinding>
    </DataTrigger.Binding>
    <DataTrigger.EnterActions>
        <BeginStoryboard Storyboard="{StaticResource MyStoryboard}"/>
    </DataTrigger.EnterActions>
</DataTrigger>

使用MultiDataTrigger通常可以避免使用多值转换器。请参见今天发布的这个问题 - Clemens
如果其中一种方法需要比另一种方法更多的努力,那将纳入我的计算中。在这种情况下,任何一种方法都需要使用转换器 - 实际上我有适当的转换器可用,并不需要编写它们,但即使我没有,也不会(在这种情况下)使一种方法比另一种更具吸引力。 - mcwyrm
你的两个示例都需要一个转换器,所以如果你还没有实现它们,我会选择使用 MultiDataTrigger 解决方案,因为 SomeConverter 更有可能在其他地方被使用,而 fooConv 则不太可能在其他地方被使用。 - Novitchi S
这似乎是正在形成的共识。我正在使用的多转换器只是对其值执行&&操作,我经常使用它,尽管我有点模糊地想知道是否有更简单的方法。 - mcwyrm
2个回答

16

Multibinding(多绑定)在除了使用 StringFormat 的极少数情况下都需要转换器。

MultiTrigger(多触发器)只需要转换器将绑定结果转换为 boolean 值。


抛开编写转换器可能需要的时间,有没有特别的理由要避免使用它? - mcwyrm
7
只有努力。我发现这是一种强大的激励方式 :D - Gusdor

5

我想再详细解释一下。

对于我来说,MultiBindingMultiDataTrigger 本质上是不同的,尽管在某些情况下你可以使用两者实现相同的功能,但这感觉有点像一个妥协,让两者以相同的方式工作。

MultiDataTrigger 应该在需要满足多个条件才能单独执行操作(例如设置属性值、启动动画等)时使用。例如,你需要 A 为 true,而 B 为 false。这两个条件可以分别被解释。这就是这个问题的情况。

另一方面,MultiBinding 应该在需要多个参数计算单个输出的情况下使用。这个输出需要对你设置的属性具有某种值。例如,只有当 A 等于 B 时,你才会更改属性值。当你在多个控件上使用相同的样式时,这是有意义的(比如 TextBlock 的 Text 属性)并且 B 是来自 ViewModel 的一个属性。所以我们可能要解决的问题是:在我的视图中的所有 TextBlock 中,将与 ViewModel 中的 SelectedText 属性相同的文本的前景色设置为闪烁(颜色变化动画)。

在你的示例中,我会使用 MultiDataTrigger,因为你的条件可以分别评估。否则,你的 MultiValueConverter 将只检查第二个条件,忽略第一个条件,并且实际上没有任何作用成为一个真正的 MultiDataTrigger。

我将留下 XAML 代码,该代码是我上面提到的使用 DataTriggerMultiBinding 的示例(我假设你正在使用 MVVM 模式)。

<Style TargetType="{x:Type TextBlock}" x:Key="SelectedTextStyle">
    <Setter Property="FontFamily" Value="Segoe UI Light"/>
    <Setter Property="FontSize" Value="24"/>
    <Setter Property="HorizontalAlignment" Value="Left"/>
    <Style.Triggers>
        <DataTrigger Value="True">
            <DataTrigger.Binding>
               <MultiBinding Converter="{StaticResource StringsToBooleanConverter}">
                    <Binding Path="SelectedText"/> <!--This is a property of the View Model-->
                    <Binding RelativeSource="{RelativeSource Self}" Path="Text"/> <!--This is the Dependency Property 'Text' of the TextBlock control-->
                </MultiBinding>
            </DataTrigger.Binding>
            <DataTrigger.EnterActions>
                <BeginStoryboard>
                    <Storyboard>
                        <ColorAnimation Storyboard.TargetProperty="Foreground.Color" Duration="0:0:2" From="Black" To="DarkOrange" AutoReverse="True" FillBehavior="HoldEnd" RepeatBehavior="Forever"/>
                    </Storyboard>
                </BeginStoryboard>
            </DataTrigger.EnterActions>
            <DataTrigger.ExitActions>
                <BeginStoryboard>
                    <Storyboard>
                        <ColorAnimation Storyboard.TargetProperty="Foreground.Color" Duration="0:0:0" From="DarkOrange" To="Black" FillBehavior="HoldEnd"/>
                    </Storyboard>
                </BeginStoryboard>
            </DataTrigger.ExitActions>
        </DataTrigger>
    </Style.Triggers>
</Style>

我完全不理解这个。如果我需要A为真,B为假 - 这是您指出MultiDataTrigger最合适的情况 - 那么有一个值(输出)只有知道A和B才能计算,这是您说MultiBinding更合适的情况。 - mcwyrm
除了这种简单的情况(A == True && B == False),您不需要使用转换器来计算输出。您可以分别评估这两个值。因此,您可以使用MultiDataTrigger。另一方面,如果您的测试用例是类似于A > B的情况,则需要使用转换器并同时评估两个值。您需要使用MultiBinding。 - Daniel Marques
除了个人喜好之外,这是基于什么的? - mcwyrm
不像编程中的大多数事情一样。 - Daniel Marques

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接