My WPF application has a DataGrid
control in it. I have a default custom style for the DataGridRow
class which works well. However, for this one particular DataGrid
on this one particular screen, I need a different custom style.
The Items in each row have a bool
property that, when set, I want to display that row with a different foreground and background color. However, when the row is selected AND when that property is set, I want a different foreground and background color to show that it's selected AND the property is set to true.
Here's what I've tried:
<Style TargetType="DataGridRow" x:Key="CameraStyle">
<Setter Property="Foreground" Value="{DynamicResource TextForeground}" />
<Setter Property="Background" Value="{DynamicResource DataBackground}" />
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Property="IsSelected" Value="False" />
<Condition Binding="{Binding Path=IsInLiveMode}" Value="True" />
</MultiDataTrigger.Conditions>
<Setter Property="Foreground" Value="Red" />
<Setter Property="Background" Value="Yellow" />
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Property="IsSelected" Value="True" />
<Condition Binding="{Binding Path=IsInLiveMode}" Value="True" />
</MultiDataTrigger.Conditions>
<Setter Property="Background" Value="DarkOrange" />
<Setter Property="BorderBrush" Value="{DynamicResource DataBorder}" />
<Setter Property="Foreground" Value="DarkRed" />
</MultiDataTrigger>
</Style.Triggers>
</Style>
This gives me a "Binding must be non-null" error, which I think is happening because there is no Binding
property on the first condition in the MultiDataTrigger.
What is the correct way to write this in XAML?
EDIT:
After trying nemesv's & Rachel's answer, the code now compiles and runs. However, the colors I've chosen for the IsSelected = true and IsInLiveMode = true case are not showing up. Here's what I have now:
<Style TargetType="DataGridRow" x:Key="CameraStyle">
<Setter Property="Background" Value="{DynamicResource DataBackground}" />
<Setter Property="Foreground" Value="{DynamicResource TextForeground}" />
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding Path=IsSelected, RelativeSource={RelativeSource Self}}" Value="False" />
<Condition Binding="{Binding Path=IsInLiveMode}" Value="True" />
</MultiDataTrigger.Conditions>
<Setter Property="Background" Value="Yellow" />
<Setter Property="Foreground" Value="Red" />
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding Path=IsSelected, RelativeSource={RelativeSource Self}}" Value="True" />
<Condition Binding="{Binding Path=IsInLiveMode}" Value="False" />
</MultiDataTrigger.Conditions>
<Setter Property="Background" Value="{DynamicResource DataBackgroundSelected}" />
<Setter Property="BorderBrush" Value="{DynamicResource DataBorder}" />
<Setter Property="Foreground" Value="{DynamicResource DataForegroundSelected}" />
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding Path=IsSelected, RelativeSource={RelativeSource Self}}" Value="True" />
<Condition Binding="{Binding Path=IsInLiveMode}" Value="True" />
</MultiDataTrigger.Conditions>
<Setter Property="Background" Value="DarkOrange" />
<Setter Property="BorderBrush" Value="{DynamicResource DataBorder}" />
<Setter Property="Foreground" Value="DarkRed" />
</MultiDataTrigger>
</Style.Triggers>
</Style>
Any ideas on why the case in question isn't working?
XAML Values MultiTrigger enables you to set property values or start actions based on a collection of Condition objects. A condition is met when the value of the property (specified by the Property property of the Condition class) of the element matches the specified Value.
Triggers are used to create visual effects on controls and framework elements. Triggers are parts of styles and are always defined inside a style. Basically, there are 3 types of triggers, they are: Property Trigger.
There are five types of triggers supported by WPF; they are: Property Trigger. Data Trigger. MultiTrigger.
Your assumptution is correct regarding the missing binding.
From MSDN MultiDataTrigger.Conditions:
For a MultiDataTrigger, each condition in the collection must set both the Binding and Value properties.
You can solve this using RelativeSource Self to refer yourself in the binding:
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding RelativeSource={RelativeSource Self},
Path=IsSelected}" Value="True" />
<Condition Binding="{Binding Path=IsInLiveMode}" Value="True" />
</MultiDataTrigger.Conditions>
You're using a MultiDataTrigger
, which is still a DataTrigger
and expects a binding
Switch Property="IsSelected"
in your Condition
to
<Condition Binding="{Binding IsSelected, RelativeSource={RelativeSource Self}}"
Value="True" />
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With