Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MultiDataTrigger vs DataTrigger with multibinding

I encountered a situation where I can easily achieve the same functionality by using a MultiDataTrigger or, alternately, using a DataTrigger with a MultiBinding. Are there any substantive reasons to prefer one approach over the other?

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

With 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>
like image 331
mcwyrm Avatar asked Jan 08 '14 10:01

mcwyrm


2 Answers

Multibinding requires a converter for all but the rarest circumstances (using StringFormat).

MultiTrigger only requires a converter to get your binding results into booleans.

like image 94
Gusdor Avatar answered Oct 11 '22 08:10

Gusdor


I would like to elaborate a little bit more.

For me, MultiBinding and MultiDataTrigger are fundamentally different and although in some situations you can use both to achieve the same functionality, it feels kind of like a hack to make both work the same way.

MultiDataTriggers should be used when you need more than one condition to be met separately so that you can do an action (set a property value, begin an animation etc). For example, you need A to be true and B to be false. Both of these conditions can by themselves be interpreted separately. It's the case of this question.

MultiBindings, on the other hand, should be used when you need more than one parameter to calculate a single output of your choice. This output would need to be of some value for you to set the property. For example, you will only change the property value if A equals B. This makes sense when you use the same style on multiple controls and A is a property of the control (say, the Text property of a TextBlock) and B is a single property from the View Model named "SelectedText". So a problem we might be trying to solve is this: among all the TextBlocks on my View, set the foreground of the one with the same Text as the property SelectedText from my View Model to blink (color changing animation).

In your example, I would use a MultiDataTrigger since your conditions can be evaluated separately. Otherwise your MultiValueConverter would only check for your second condition, ignoring the first one and would serve no real purpose for being a MultiDataTrigger really.

I'll leave the XAML for the example where I'd use the DataTrigger with MultiBinding that I mentioned above: (I assume you are using the MVVM pattern)

<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> 
like image 37
Daniel Marques Avatar answered Oct 11 '22 09:10

Daniel Marques