What's the right way to trigger on multiple conditions in a WPF Style
Solution 1
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>
Solution 2
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" />
Tony Vitabile
Updated on July 09, 2022Comments
-
Tony Vitabile almost 2 years
My WPF application has a
DataGrid
control in it. I have a default custom style for theDataGridRow
class which works well. However, for this one particularDataGrid
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?
-
Tony Vitabile over 11 yearsRachel: I wish I could check off yours and @nemesv's answers as the correct answer, because you're both right. But nemesv did answer first, so he gets the checkmark.
-
Tony Vitabile over 11 yearsnemesv: Thanks, that at least doesn't throw any errors. There is still a problem. Please look at my edits to my original question.
-
Rachel over 11 years@TonyVitabile That's fine, I think his answer is better anyways because of the MSDN links, and already gave him a +1 for it :)