MultiTrigger: Condition Binding to DependencyProperty doesn't work

11.5k Views Asked by At

I have a custom button MainMenuButton of type UserControl and atm I'm styling it. Now I wanted to implement a MultiTrigger to only change the appearance of the button if two conditions are met.

The first condition is if IsMouseOver == true. I simply put the following Condition:

<MultiTrigger>
    <MultiTrigger.Conditions>
        <Condition Property="IsMouseOver" Value="True"/>
    </MultiTrigger.Conditions>
    <MultiTrigger.EnterActions>
        <Setter TargetName="LayoutRoot" Property="Background" Value="Red">
    </MultiTrigger.EnterActions>
    <MultiTrigger.ExitActions>
        <Setter TargetName="LayoutRoot" Property="Background" Value="Black">
    </MultiTrigger.ExitActions>
</MultiTrigger>

The second condition is related to a DependencyProperty:

public static readonly DependencyProperty IsCheckedProperty = DependencyProperty.Register("IsChecked", typeof(bool), typeof(MainMenuButton), new PropertyMetadata(false));

In another SO post a user said that I can use DataTrigger to react to IsCheckedProperty. So I tried the code from the other post but it didn't work:

<MultiTrigger>
    <MultiTrigger.Conditions>
        <Condition Property="IsMouseOver" Value="True"/>
        <Condition Binding="{Binding RelativeSource={RelativeSource Mode=Self}, Path=IsChecked}" Value="False"/>
    </MultiTrigger.Conditions>
    <MultiTrigger.EnterActions>
        <BeginStoryboard Storyboard="{StaticResource MouseEnter}"/>
    </MultiTrigger.EnterActions>
    <MultiTrigger.ExitActions>
        <BeginStoryboard Storyboard="{StaticResource MouseLeave}"/>
    </MultiTrigger.ExitActions>
</MultiTrigger>

How can this be solved? Thanks for any answers! :)

5

There are 5 best solutions below

0
On BEST ANSWER

Got it to work in the mean time. I stumbled upon this blog article which contains a working solution: http://anders.janmyr.com/search?q=multidatatrigger

Changed my code to the following:

<MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                    <Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsMouseOver}" Value="True"/>
                    <Condition Binding="{Binding RelativeSource={RelativeSource Mode=Self}, Path=IsChecked}" Value="True"/>
                </MultiDataTrigger.Conditions>
                <Setter TargetName="LayoutRoot" Property="Background" Value="Red"/>
            </MultiDataTrigger>

Now it works. Anyway thanks to all answerers for their effort!

1
On
<Window x:Class="DataBinding.MultiTrigger"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MultiTrigger" Height="300" Width="300">
<Window.Resources>
    <Style TargetType="Button">
        <Style.Setters>
            <Setter Property="Background" Value="BlueViolet"></Setter>
            <Setter Property="Foreground" Value="Red"></Setter>
        </Style.Setters>
        <Style.Triggers>
            <MultiTrigger>
                <MultiTrigger.Conditions>
                    <!--Use only one conditions for Implementations-->
                    <Condition Property="Control.IsFocused" Value="True"></Condition>
                    <Condition Property="Control.IsMouseOver" Value="True"></Condition>
                </MultiTrigger.Conditions>
                <MultiTrigger.Setters>
                    <Setter Property="Background" Value="Green"></Setter>
                    <Setter Property="Foreground" Value="White"></Setter>
                </MultiTrigger.Setters>
            </MultiTrigger>
        </Style.Triggers>
    </Style>
</Window.Resources>
<Button Height="50">The World Game</Button>

0
On

I guess in your style you haven't specified the correct TargetType. This should work -

<Style TargetType="{x:Type local:MainMenuButton}">
   <MultiTrigger>
    <MultiTrigger.Conditions>
        <Condition Property="IsMouseOver" Value="True"/>
        <Condition Binding="IsChecked" Value="False"/>
    </MultiTrigger.Conditions>
    // Your setter goes here
</MultiTrigger>
</Style>

Namespace local should be added in xaml which corresponds to the namespace where your MainMenuButton class resides.

2
On

I think you dont need to bind to your DP, try using just Property="IsChecked" as for the IsMouseOver.

0
On

If anyone is still looking for answers to this, I came across this and tried using

<MultiTrigger>
    <MultiTrigger.Conditions>
        <Condition Binding="{...}" Value="..."/>
    </MultiTrigger.Conditions>
</MultiTrigger>

as some answers sugggest but WPF throws an exception that 'Property' must not be null for MultiTrigger. The solution if you want to use bindings in the trigger conditions is to use MultiDataTrigger.

<MultiDataTrigger>
    <MultiDataTrigger.Conditions>
        <Condition Binding="{...}" Value="..."/>
    </MultiDataTrigger.Conditions>
</MultiDataTrigger>

MultiTrigger works with 'Property' while MultiDataTrigger works with bindings.