Click here to Skip to main content
15,879,095 members
Articles / Desktop Programming / XAML

Changing the background color for one or more columns in a Silverlight DataGrid

Rate me:
Please Sign up or sign in to vote.
5.00/5 (10 votes)
2 Jan 2010CPOL3 min read 66.9K   672   10   6
Column.BackgroundColor = "Yellow"? I wish.

Introduction

This is something you would think would be pretty simple, but it isn't, unless I'm missing something. I thought I'd write a little step by step of how I arrived at the solution I came up with in case I took a more difficult path than I needed to and someone can point out where I took a wrong turn.

Background

Here is the basic XAML for a DataGrid and what it looks like in the browser. You have sorting, validation, and two way binding, which is pretty nice:

1-code.jpg

1-result.jpg

The dilemma

All this works fine and until someone says they want the first two columns read-only and they want the third column with a yellow background so the user can easily tell which columns are editable. "No problem" you say, whereupon you become perplexed at the curious lack of a Background or a BackgroundColor property in the text column:

2-code.jpg

You, being an industrious person not easily discouraged by such trifles, decide to turn to the templated cell to gain more control over what is going on, making a template for the read only view (a TextBlock) and for the edit mode (a TextBox). The TextBox does have a Background property, sweet success! But the TextBlock doesn't have a Background property, crushing defeat. To add insult to injury, now sorting and validation don't work either. But, we do have a different background color in edit mode, so that is progress of a sort.

3-code.jpg

3-result.jpg

Utilizing your finely honed Google-Fu, you correct the two issues just created, with the following:

4-code.jpg

And then, if the TextBlock doesn't have a Background property, let's just throw something behind it that does, like a Border, and we should be all done, right?

5-code.jpg

5-result.jpg

Well, that's pretty close, but now, as we mouse over the rows, we don't see the nice highlight effect that was there, and it just, generally, doesn't look that great. It would be nice if we could still have the nice UI cues that were there in the first place, but just, well, with a different background color. At this point, you may start pondering a dive into the visual state manager and animations, but as you watch everyone else leaving the office, you start wondering why you've been spending all day messing with the background color of a column.

Ignoring this irrelevant piece of information, you sense inspiration, and think, "Ah! if the background were only partially visible, the existing animation might be more visible, and no additional work would be needed!"

6-code.jpg

Which is kinda true... Except now, the font is slightly transparent as well, and no amount of font bolding or manual setting of opacity seems to help:

6-result.jpg

7-code.jpg

Cursing the stars and heavens while simultaneously pounding your keyboard with your elbows, you accidentally stumble into this, which does work! Eureka, you have done it!

8-code.jpg

8-result.jpg

Except... You feel kind of dirty because in order to change the *&#$^*&^$% background color, you have exploded one line of XAML into 15, which seems excessive. Furthermore, there is great redundancy in the name of the column, the background color used, and you are going to have to copy and paste this multiple times for multiple columns. You briefly consider using a style, but that will only get you so far since you'd still have to specify the two templates for each column using this method.

A voice in the back of your head is telling you to set fire to this DataGrid and look into vendor grids, but no, you won't be undone by these minor issues.. You will find a way to beat this issue into submission. Shortly before running out of curse words and keyboards, you arrive at the final solution which looks and acts exactly like how you would expect it to:

final-code.jpg

final-result.jpg

C#
public class DataGridTextColumnExtended : DataGridTemplateColumn
{
    public string Background { get; set; }

    public string BindingProperty
    {
        set
        {
            if (value == null)
                throw new ArgumentNullException("BindingProperty");

            //otherwise sort won't work on template column
            base.SortMemberPath = value.ToString();

            CellTemplate = (DataTemplate)XamlReader.Load(@"
             <DataTemplate 
               xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'>
             <Border Background='" + Background + @"' Opacity='.5' />
             <TextBlock Text='{Binding Path=" + value + @"}' Margin='4' />
             </DataTemplate>
             ");

            CellEditingTemplate = (DataTemplate)XamlReader.Load(@"
             <DataTemplate 
               xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'>
             <TextBox Background='" + Background + @"' Text='{Binding 
             NotifyOnValidationError=True, ValidatesOnExceptions=True, 
             Path=" + value + @", Mode=TwoWay}' />
             </DataTemplate>
             ");

            _BindingProperty = value;
       }

       get
       {
           return _BindingProperty;
       }
    }
    private string _BindingProperty = null;
}

Enjoy!

Points of Interest

No actual keyboards or desks were harmed in the making of this article.

Also, if you have a cleaner way of creating the custom column with the code being in a separate XAML file instead of C# (while keeping the usage XAML the same), I'd love to hear about it.

History

  • 2-Jan-2010 - Initial version.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United States United States
I've been a software developer since 1996 and have enjoyed C# since 2003. I have a Bachelor's degree in Computer Science and for some reason, a Master's degree in Business Administration. I currently do software development contracting/consulting.

Comments and Discussions

 
GeneralExtraordinarily funny... Pin
Drazen Dotlic2-Nov-14 23:30
Drazen Dotlic2-Nov-14 23:30 
BugLittle bug on the DataGridTextColumnExtended class in the article Pin
diego mesa tabares22-Aug-13 11:59
diego mesa tabares22-Aug-13 11:59 
QuestionGreat article! Pin
mikethedarv27-Feb-12 12:44
mikethedarv27-Feb-12 12:44 
QuestionHaving a problem with highlighting a cell when mouse over Pin
andrey_Itra27-Sep-11 3:57
andrey_Itra27-Sep-11 3:57 
My issue is that when I'm moving a mouse over a row then all cells except those in colored columns are highlighted with lighter color. The cells in highlighted columns are still have a color I specified for the column. How can I make a cell to be highlighted when mouse moved?
GeneralAmusing article... Pin
Andrew Rissing6-Jan-10 4:10
Andrew Rissing6-Jan-10 4:10 
GeneralNice example of extending a class Pin
kelly3175-Jan-10 6:04
kelly3175-Jan-10 6:04 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.