Friday, March 21, 2014

Set DataGrid Cell Color Based on Cell Value

If you work with the WPF DataGrid, and you would like to set the color of a cell depending on whether the cell value exceeds a certain parameter here is how you could do it.

First, you need to create a custom class that would return true or false depending on whether the incoming value is greater than the specified parameter. Your custom class should implement the IValueConverter interface.

public class MyNumberToBoolConverter : IValueConverter
    {
        public object Convert(object value, Type targetType,
            object parameter, CultureInfo culture)
        {                        

            double dValue = System.Convert.ToDouble(value);
            double dParameter = System.Convert.ToDouble(parameter);

            return (dValue >= dParameter);             
        }

        public object ConvertBack(object value, Type targetType,
            object parameter, CultureInfo culture)
        {            
            return null;
        }
    }

Declare the class in your XAML:

<Window.Resources>
<local:MyNumberToBooleanConverter x:Key="numberToBool" />
</Window.Resources>

Create a style to be used for your DataGrid with 2 data triggers, one for the true value, and the other for the negative value:

<Style x:Key="PriceChangeStyle" TargetType="DataGridCell">
          <Style.Triggers>
             <DataTrigger Binding="{Binding YourDataField, 
                     Converter={StaticResource numberToBool}, ConverterParameter=0}" 
                     Value="True">
                    <Setter Property="Foreground" Value="Green"></Setter>
                </DataTrigger>
                 <DataTrigger Binding="{Binding YourDataField, 
                     Converter={StaticResource numberToBool}, ConverterParameter=0}" 
                     Value="False">
                    <Setter Property="Foreground" Value="Red"></Setter>
                </DataTrigger>
            </Style.Triggers>
 </Style>

The converter paramer we use is 0. So if the value in your data field is greater than 0, the cell foreground is set to green, otherwise it is set to red.

Now, all that is left to do is to use the style with your DataGrid:

<DataGrid …
  CellStyle="{StaticResource PriceChangeStyle}"..>        

If you don’t want some datagrid cells to be affected by the data trigger, you can specify the foreground value explicitly:

<DataGridTextColumn Header="MyHeader" Binding="{Binding Path=MyDataField2}" Foreground="Blue"/>