I'm stuck at changing a color if a number is greater than zero in my DataGrid
.
I tried IValueConverter
, but can't really make it work. It only works if I already know the value in the DataGrid
.
This is my XAML. The green color is the one I can make work
with the code below it. I tried to bind it with the IValueConverter
.
<DataGrid x:Name="dg_ProductlistGrid" ItemsSource="{Binding ProductCollection}" AutoGenerateColumns="False" IsReadOnly="True" Loaded="form1_load">
<DataGrid.ColumnHeaderStyle>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="BorderBrush" Value="Black"/>
<Setter Property="BorderThickness" Value="1,1,1,1"/>
<Setter Property="Padding" Value="30,9,12,6"/>
</Style>
</DataGrid.ColumnHeaderStyle>
<DataGrid.Columns>
<DataGridTextColumn Header="ProduktID" Binding="{Binding Path=factProduct.ProductId}" Width="*" IsReadOnly="True"/>
<DataGridTextColumn Header="Navn" Binding="{Binding Path= factProduct.Name}" Width="*" IsReadOnly="True"/>
<DataGridTextColumn Header="Mængde" Binding="{Binding Path =QauntityNeeded }" Width="*" IsReadOnly="True"/>
<DataGridTextColumn Header="Rigtige Mængde" Binding="{Binding Path =FoundQauntity }" Width="*" IsReadOnly="True"/>
<DataGridTextColumn Header="Mangel" Binding="{Binding Path = Missing}" Width="*" IsReadOnly="True">
<DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}">
<Style.Triggers>
<Trigger Property="Text" Value="0">
<Setter Property="Background" Value="LightGreen"/>
</Trigger>
<Trigger Property="Text" >
<Setter Property="Background" Value="{Binding Path=Missing, Converter={StaticResource converter}}"/>
</Trigger>
</Style.Triggers>
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
This is my IValueConverter
:
public class Greaterthan : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
int input = (int)value;
if (input < 1)
{
return new SolidColorBrush(Colors.Red);
}
else
return DependencyProperty.UnsetValue;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
How do I solve this?
Your converter does not check if the value is greater than zero, but if it is smaller than one. You can simplify your converter and make it more powerful at the same time. Expect the greater than value as parameter for the converter. Although you can specify an int
in XAML as a parameter, it is more readable to specify the value as a string
, as you will below when using the converter. This converter parses the string
value and parameter as int
and returns whether the value is greater than the parameter as bool
.
public class GreaterThanConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (!(value is string valueText) ||
!(parameter is string parameterText) ||
!int.TryParse(valueText, out var intValue) ||
!int.TryParse(parameterText, out var intParameter))
return Binding.DoNothing;
return intValue > intParameter;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
In XAML you can use a DataTrigger
with a binding to Text
that uses the converter. If the converter returns true
(meaning the value is greater than the parameter), a specific color is set.
<DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}">
<Style.Triggers>
<Trigger Property="Text" Value="0">
<Setter Property="Background" Value="LightGreen"/>
</Trigger>
<DataTrigger Binding="{Binding Text, RelativeSource={RelativeSource Self}, Converter={StaticResource GreaterThanConverter}, ConverterParameter=0}" Value="True">
<Setter Property="Background" Value="Red"/>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGridTextColumn.ElementStyle>
Make sure to instantiate the converter in any resource dictionary, e.g. on the DataGrid
, otherwise you will get an error that the resource cannot be resolved.
<DataGrid>
<DataGrid.Resources>
<local:GreaterThanConverter x:Key="GreaterThanConverter"/>
</DataGrid.Resources>
<!-- ...other markup. -->
</DataGrid>
Also make sure that you defined the local
namespace in the XAML file.
xmlns:local="clr-namespace:MyWpfApp.MyNamespace"