2008-06-03

DataGridView style inheritance

Interesting "feature" in .Net Windows Forms 2.0 DataGridView. We have a DGV that is initialized in code. At the top of the initialization code is this statement:

dgv.RowsDefaultCellStyle.ForeColor = Color.Black;
dgv.DefaultCellStyle.SelectionBackColor = Color.MediumBlue;
dgv.DefaultCellStyle.SelectionForeColor = Color.White;

Then, columns are created and added:

DataGridViewTextBoxColumn c = new DataGridViewTextBoxColumn();
c.Name = "Foo";
...
c.DefaultCellStyle.Format = "0.00";
c.DefaultCellStyle.ForeColor = Color.Red;
c.DefaultCellStyle.SelectionForeColor = Color.Red;
dgv.Columns.Add(c);

Guess what? The text is not red. Unless it's selected, then it is red. In order to force the text to turn red, I have to do this, after the DataSource is set:

foreach (DataGridViewRow r in dgv.Rows) {
   r.Cells["Foo"].Style.ForeColor = Color.Red;
}

Apparently, the column's DefaultCellStyle is ignored. Actually, it's overridden by the grid's RowsDefaultCellStyle, which is exactly backwards of what I would expect (RowsDefaultCellStyle and AlternatingRowsDefaultCellStyle should be higher up the override hierarchy, because they're more generic, describing an unbound range of rows, than a specific column's DefaultCellStyle).

What's even more frustrating, is that sorting the grid causes the individual styles to be conveniently forgotten. So, I have to add that same loop (or, to be more proper, move the loop to a function, call it from the DataBind event, and add a call...) to the DataGridView's Sorted event.

This was one of those problems that, once I figured out what was going on, only then was I able to google and find the articles that described it. And apparently it's not new, just news to me. I still find it backwards, requiring a whole lot of extra work to make it behave the right way; and thus I reserve the right to complain.

1 comment:

TommyG said...

I, like you, have found their behaviour very inconsistent. This (http://msdn.microsoft.com/en-us/library/1yef90x0.aspx) describes how the behaviour should be, however I find that this only counts for grid-wide style, not cell or row specific styles.

What does work quite well for me, though, is responding to the DataGridView.CellFormatting event, and setting the cell colours to what I want.

Hope this helps.