Home > other >  Changing background color of cells if a value is greater than or equal to
Changing background color of cells if a value is greater than or equal to

Time:09-29

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?

CodePudding user response:

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 Greaterthan : 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 converter}, ConverterParameter=0}" Value="True">
            <Setter Property="Background" Value="Red"/>
         </DataTrigger>
      </Style.Triggers>
   </Style>
</DataGridTextColumn.ElementStyle>

CodePudding user response:

In your case it would be better to move the complete logic to pick the color to the converter. You should then remove all triggers and bind DataGridCell.Background directly to the current value of Missing. You can also use DataGridTextColumn.CellStyle instead of the EditStyle.

<DataGrid>
  <DataGrid.Resources>
    <IntegerToBrushConverter x:Key="IntegerToBrushConverter" />
  </DataGrid.Resources>

  <DataGrid.Columns>
    <DataGridTextColumn Binding="{Binding Missing}">
      <DataGridTextColumn.CellStyle>
        <Style TargetType="DataGridCell">
          <Setter Property="Background" 
                  Value="{Binding Missing, Converter={StaticResource IntegerToBrushConverter}}" />
        </Style>
      </DataGridTextColumn.CellStyle>
    </DataGridTextColumn>
  </DataGrid.Columns>
<DataGrid>

IntegerToBrushConverter.cs

class IntegerToBrushConverter : IValueConverter
{
  public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
  {
    switch (value)
    {
      case int numericValue when numericValue == 0: return Brushes.LightGreen; break;
      case int numericValue when numericValue > 0: return Brushes.Red; break;
      case int numericValue when numericValue > 1 && numericValue < 5: return Brushes.Blue; break;
      default: return Brushes.Green;
    }
  }

  public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    => throw new NotSupportedException();
}
  • Related