Search code examples
wpfxamldatatriggermultidatatrigger

Usage DataTrigger in WPF


I have a TextBox control defined in XAML and I want to apply different background colors to the TextBox based on its IsReadOnly or IsEnabled properties. I used dataTriggers to actually switch between the colors as shown below:

<Style x:Key="TextBoxStyle" TargetType="TextBox">
    <Style.Triggers>
        <DataTrigger Binding="{Binding IsEnabled}" Value="True">
            <Setter Property="TextBox.Background" Value="Yellow"/>
        </DataTrigger>
        <DataTrigger Binding="{Binding IsReadOnly}" Value="True">
            <Setter Property="TextBox.Background" Value="Red"/>
        </DataTrigger>
        <MultiDataTrigger>
            <MultiDataTrigger.Conditions>
                <Condition Binding="{Binding IsReadOnly}" Value="True"/>
                <Condition Binding="{Binding IsEnabled}" Value="True"/>
            </MultiDataTrigger.Conditions>
            <Setter Property="Background" Value="Green"/>
        </MultiDataTrigger>
    </Style.Triggers>
</Style>

And the TextBox is defined as shown below:

  <TextBox Name="sourceTextBox"  Margin="5,3,5,3" IsReadOnly="True" Style="{StaticResource TextBoxStyle}" />

But the problem is, the colors are not being applied properly.

Is there any problem with the above approach?


Solution

  • I think you need just need to add RelativeSource={RelativeSource Self} to your bindings:

    <Style x:Key="TextBoxStyle" TargetType="{x:Type TextBox}">
        <Style.Triggers>
            <DataTrigger Binding="{Binding IsEnabled, RelativeSource={RelativeSource Self}}" Value="True">
                <Setter Property="Background" Value="Yellow" />
            </DataTrigger>
            <DataTrigger Binding="{Binding IsReadOnly, RelativeSource={RelativeSource Self}}" Value="True">
                <Setter Property="Background" Value="Red" />
            </DataTrigger>
            <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                    <Condition Binding="{Binding IsReadOnly, RelativeSource={RelativeSource Self}}" Value="True"/>
                    <Condition Binding="{Binding IsEnabled, RelativeSource={RelativeSource Self}}" Value="True"/>
                </MultiDataTrigger.Conditions>
                <Setter Property="Background" Value="Green"/>
            </MultiDataTrigger>
        </Style.Triggers>
    </Style>
    

    There is still one problem however, I don't believe you will ever see a Red background because a TextBox with its IsEnabled property set to False has a built in background color into its control template that will take priority over your style's trigger's setter.

    I think you'd have to redefine its control template to change the background color when the TextBox is disabled.