Hey, I'm trying to bind two properties so I can change the background color in DataGrid based on their value. Based on these answers
I have implemented the advice in my code, but I'm missing something and it doesn't work. Thanks for any advices.
namespace Example{
public class ExampleClass {
private ExampleObject exampleObject;
public ExampleObject ExampleObject {get; set;}
}
}
namespace Object{
public class ExampleObject {
private Value value;
public ExampleObject ExampleObject {get; set;}
}
public Enum Value
{
High,
Low
}
}
Wpf DataGrid DataTrigger where I am changing the colour
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<Style.Triggers>
<DataTrigger Binding="{Binding ExampleObject.Value}" Value="{StaticResource CellConverter}">
<Setter Property="Background" Value="Green">
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding ExampleObject.Value}" Value="{StaticResource CellConverter}">
<Setter Property="Background" Value="Red">
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>
CellConvertor class
public class CellConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
Value input = ((Value)value);
switch (input)
{
case Value.High:
return "High";
case Value.Low:
return "Low";
default:
return DependencyProperty.UnsetValue;
}
}
}
CodePudding user response:
You must fix the trigger condition in your example.
Additionally, in order to bind to the ExampleObject.Value
enum value, the ExampleObject.Value
must be a public
property:
public class ExampleObject
{
public Value Value {get; set;}
}
In XAML you reference enum
values like static variables and constants by using the x:Static
markup extension. In fact, C# enum
is implemented as a set of constants. When using the x:Static
extension, your current value converter CellConverter
becomes obsolete:
<!--
In this example the namespace that defines the enum type 'Value'
is assumed to be registered under the XAML alias 'local'
-->
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<Style.Triggers>
<DataTrigger Binding="{Binding ExampleObject.Value}"
Value="{x:Static local:Value.Low}">
<Setter Property="Background" Value="Green" />
</DataTrigger>
<DataTrigger Binding="{Binding ExampleObject.Value}"
Value="{x:Static local:Value.High}">
<Setter Property="Background" Value="Red" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>
Remarks: in general, if you want to use a value converter, then you must configure the Binding
accordingly and assign the IValueConverter
instance to the Binding.Converter
property. You can't assign a IValueConverter
directly to a property to make it convert. The IValueConverter
must receive an input that he can convert to produce the output. The input is the value provided by the actual Binding
(and that's why Binding
has a Binding.Converter
property - they always go in tandem).
See Microsoft Docs: DataBinding Overview (Data conversion)
Note, since the property DataTrigger.Value
is not a DependencyProperty
, you can't define its value via a Binding
.
Converter example:
<Window>
<Window.Resources>
<MyValueConverter x:Name="MyValueConverter" />
</Window.Resources>
<SomeObject SomeDependencyProperty="{Binding SourceProperty, Converter={StaticResource MyValueConverter}}" />
</Window>
It's also recommende best practice to define a default enum value to avoid errors. The default value for an enum instance is always 0
which in your case would default to High
. Better allow to identify an unset state by adding an explicit 0
value named None
or Default
:
public enum Value
{
None = 0,
High,
Low
}