This question popped up on StackOverflow
and it prompted me to write some code. At first I thought, “Okay, someone will answer this soon, I’m sure.” But after I left it alone all night and returned in the morning I found it still unanswered. As I find this to be a common request when it comes to DataGrids I decided to write some code and figure it out myself.

The solution is posted on the StackOverflow thread. I wrote a small demo application to show how this works. You can download it here. For posterity sake, I’ll repeat the solution here.

Don’t Fight The Framework

A note on WPF: If you read the original question on StackOverflow, you’ll notice the original poster was trying to accomplish their goal via code-behind. This is simply the wrong way to go about using WPF. It’s a classic case of developer with WinForms experience trying to use the WinForms sledgehammer to make WPF do their bidding. Wrong approach.

WPF is a totally different animal than classic WinForms. It is more robust, to be sure, and that can translate into “more complex” with a “steeper learning curve”. But the end result is a technology that is far more flexible and powerful than it’s pathetic predecessor. Learning how the technology expects you to do things is the first step in leveraging the power of technology to do your bidding.

In this particular case, what we need to understand is that WPF is setup very nicely to handle styling of visual elements. In this specific case, it’s a prime candidate for an IValueConverter implementation and a simple styling rule.

Setting The Style

Like all controls, the DataGrid can be styled, and these style settings can target specific elements of the grid. In this case, we want to style the DataGridCell’s Background property. We’ll do that by declaring a style setting within the DataGrid XAML markup:

<toolkit:DataGrid.CellStyle>
          <Style TargetType="{x:Type toolkit:DataGridCell}">
            <Style.Setters>
              <Setter Property="Background" 
                   Value="{Binding RelativeSource={RelativeSource Self}, 
                   Path=Content.Text, 
                   Converter={StaticResource dataGridCellTextToColorConverter}}" />
            </Style.Setters>
          </Style>
        </toolkit:DataGrid.CellStyle>

What we’re doing here is declaring a style for the DataGridCell. We’re specifying the Background as the property to set, and we’re saying that we’re going to allow an IValueConverter (dataGridCellTextToColorConverter) to handle the calculation of the exact value to set. We’re passing the converter the value of the DataGridCell’s Content.Text property.

Coding The IValueConverter

IValueConverter is a really simple interface to implement. In this case, we’re only concerned with the Convert() method because we’re only binding values one-way.

Note: I’ve done some extra work here in the constructor of this class to codify a dictionary of text values and colors. You could do this sort of thing a lot of different ways; you could pull these values from a database on application startup and cache them in your app if you wanted to; whatever you feel like doing. I did this for ease of use.

public class DataGridCellTextToColorConverter : IValueConverter
  {
    public IDictionary _colors;
    public DataGridCellTextToColorConverter()
    {
      _colors = new Dictionary();
      _colors["COMEDY"] = "GREEN";
      _colors["SCIENCE FICTION"] = "RED";
      _colors["DRAMA"] = "ORANGE";
    }
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
      if (value == null) return Colors.White.ToString();
      foreach(var color in _colors)
      {
        if (value.ToString().ToUpper().Contains(color.Key))
          return color.Value;
      }
      return "WHITE";
    }
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
      throw new NotImplementedException();
    }
  }

Here, we’re checking the colors dictionary to see if any text keys match, and if so, we’re returning the corresponding color value. In WPF, the colors are HTML color values, so you can use named colors from the HTML color table or you can use values like #006688.

Resource Declaration

Once the IValueConverter is coded, we simply need to reference it in our view as an appropriate Resource.

<Window.Resources>
    <Converters:DataGridCellTextToColorConverter x:Key="dataGridCellTextToColorConverter"/>
  </Window.Resources>

And with that, you should have a working method for changing the colors on a DataGrid based on values in the cell. Enjoy.

Leave a Reply

You must be logged in to post a comment.