Slippy
Slippy

Reputation: 61

WPF DataGrid Coloring - Custom Coloring For Both Rows and Cells

I have a WPF DataGrid control that uses custom coloring for both the data rows and individual data cells. Some rows need to be colored, but there are also some individual cells that need to show a specific color regardless of their row's background color. I am handling the coloring like this:

<DataGrid.Resources>
            <!--Row Coloring-->
            <Style TargetType="DataGridRow" >
                <Style.Triggers>
                    <DataTrigger Binding="{Binding IsInactive}" Value="True">
                        <Setter Property="Background" Value="DarkGray" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
            <!--Cell Coloring-->
            <local:ColorConverter_RunToday x:Key="converter_RunToday"/>
            <Style TargetType="DataGridCell" >
                <Style.Triggers>
                    <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=Column.Header}" Value="Run Today">
                        <Setter Property="Background" Value="{Binding RelativeSource={RelativeSource Self}, Path=Content.Text, Converter={StaticResource converter_RunToday}}"/>
                        <Setter Property="BorderBrush" Value="{Binding RelativeSource={RelativeSource Self}, Path=Content.Text, Converter={StaticResource converter_RunToday}}"/>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </DataGrid.Resources>

My color converter class is:

public class ColorConverter_RunToday : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        string str = value.ToString().Trim().ToUpper();

        if (str == "YES")
            return Brushes.LightGreen;

        return Brushes.Transparent;
    }

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

The only problem with this setup is that the "Run Today" cell with the custom coloring will never have the background color of the row. Setting the color to Brushes.Transparent still just colors the cell white if the cell's text is not "YES". In addition, when I have that row selected the custom cell does not get the normal blue highlight color.

I have previously gotten a solution to work by individually coloring each cell programmatically instead of using XAML, but it would not display correctly when scrolling unless I disabled row virtualization on the grid. This would cause it to perform terribly on a grid containing a lot of data.

Upvotes: 0

Views: 1326

Answers (1)

Rohit Vats
Rohit Vats

Reputation: 81313

It seems you are only interested in drawing cell to LightGreen for following conditions:

  1. Column name is Run Today.
  2. Cell text is Yes.
  3. Cell is not selected.

But, with converter in place you end up setting background for cells which doesn't satisfy above conditions (to Transparent) resulting in some issues. Might be overriding default values for dataGrid, so try to avoid that.

I would suggest to achieve this with MultiDataTrigger and provide above 3 conditions there. (No need for converter)

<Style TargetType="DataGridCell" >
    <Style.Triggers>
        <MultiDataTrigger>
            <MultiDataTrigger.Conditions>
                <Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=Column.Header}" Value="Run Today"/>
                <Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=Content.Text}" Value="Yes"/>
                <Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsSelected}" Value="False"/>
            </MultiDataTrigger.Conditions>
            <Setter Property="Background" Value="LightGreen"/>
            <Setter Property="BorderBrush" Value="LightGreen"/>
        </MultiDataTrigger>
    </Style.Triggers>
</Style>

Upvotes: 1

Related Questions