c# - WPF bind background color of DataGridTextColumn to color by row


Keywords:c# 


Question: 

Say I have a DataGrid with the following data:

John, Male
Mary, Female
Tony, Male
Sally, Female

The grid is bound to an ObservableCollection of Person model objects that implements INofifyPropertyChanged for the properties Person.Name and Person.Gender. I now want to bind the DataGridTextColumn's background color to the person's gender so that rows containing males are blue, and rows containing females are pink. Is it possible to do this by adding another property to the Person model like so:

public class Person
{
    public Color BackgroundColor
    {
        get
        {
            if (gender == "Male")
            {
                return Color.Blue;
            }
            else
            {
                return Color.Pink;
            }
        }
    }

if so, how do I bind this to the row or column's background color? I already have bounded columns like this:

<DataGridColumn Header="Name" Binding={Binding Name} />
<DataGridColumn Header="Gender" Binding={Binding Gender} />

3 Answers: 

Assuming that BackgroundColor is of a System.Windows.Media.Color type, and not System.Drawing.Color, if you want to change background of the entire row you can alter DataGrid.RowStyle and bind Background property to BackgroundColor property

<DataGrid ...>
    <DataGrid.RowStyle>
        <Style TargetType="{x:Type DataGridRow}">
            <Setter Property="Background">
                <Setter.Value>
                    <SolidColorBrush Color="{Binding Path=BackgroundColor}"/>
                </Setter.Value>
            </Setter>
        </Style>
    </DataGrid.RowStyle>
</DataGrid>
 

You want to implement an IValueConverter to convert a String to a Brush. See

public class StringToBrushConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var val = (string)value;
        return new SolidColorBrush(val == "male" ? Colors.Blue : Colors.Pink);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

In XAML, you'll want <Window.Resources> like

<Window.Resources>
    <local:StringToBrushConverter x:Key="stringToBrush" />
    <Style x:Key="MaleFemaleStyle" TargetType="DataGridCell">
        <Setter Property="Background" Value="{Binding Path=Gender, Converter={StaticResource stringToBrush}}" />
    </Style>
</Window.Resources>

Then apply the MaleFemaleStyle to your grid.

<DataGrid CellStyle="{StaticResource MaleFemaleStyle}">
    ...
</DataGrid>
 

This works for me

 <DataGrid.RowStyle>
    <Style TargetType="{x:Type DataGridRow}">
    <Style.Triggers>
    <DataTrigger Binding="{Binding Sex}" Value="Male">
    <Setter Property="Background" Value="Blue"/>
    </DataTrigger>
    <DataTrigger Binding="{Binding Sex}" Value="Female">
    <Setter Property="Background" Value="Red"/>
    </DataTrigger>
    </Style.Triggers>
    </Style>
    </DataGrid.RowStyle>