Microsoft Documentation :
To improve performance, the EnableRowVirtualization property is
set to true by default. When the EnableRowVirtualization property is
set to true, the DataGrid does not instantiate a DataGridRow object for
each data item in the bound data source. Instead, the DataGrid creates
DataGridRow objects only when they are needed, and reuses them as much as it
can. For example, the DataGrid creates a DataGridRow object for each data
item that is currently in view and recycles the row when it scrolls out
of view.
source : http://msdn.microsoft.com/en-gb/library/system.windows.controls.datagrid.unloadingrow.aspx
this explains the behaviour you have been experiencing
the proper (though not easier I admit) solution being, hence, to use the UnloadingRow event to unset the style you had set.
Without further details (such as the exception you are getting) its difficult to see why you are getting an exception. I suspect that the style
variable has a null reference.
I also suspect that the reason its null is that the "DataGridHeaderStyle" doesn't exist in the resource dictionary of the this
object, which I would guess is a UserControl
. In order to acquire the Style
you need to do this look up on the actual FrameworkElement
object that holds the Style
in its Resources
property. (Note programmatic access to the resources does not cascade up the visual tree searching the resource of parents).
However, assuming you can fix that you still have a problem. The use of SetValue
on the Setters
colleciton itself is nothing like what you actually need to be doing.
You need to be doing this:-
style.Setters.Add(new Setter(DataGridColumnHeader.BackgroundProperty, new SolidColorBrush(Colors.Red));
Of course this only works if the style doesn't already contain an Setter
for the property. Hence a more robust version is:-
var setter = style.Setters
.OfType<Setter>()
.Where(s => s.Property == DataGridColumnHeader.BackgroundProperty)
.FirstOrDefault();
if (setter != null)
setter.Value = new SolidColorBrush(Colors.Red);
else
style.Setters.Add(new Setter(DataGridColumnHeader.BackgroundProperty, new SolidColorBrush(Colors.Red));
Best Answer
Although the DataGrid does not expose a Header Background property, it does have a property for the ColumnHeaderStyle. Using the technique that DaniCE has previously suggested for a single column we can replace the header template for all header columns including the empty space on the right hand side. The down side with replacing the entire template for a header is that we lose the sorting arrows and separators which are present in the default header template. Fortunately we can use a template browser to extract the default template being used and then modify a copy of it.
Here I've thrown together a quick example that will change the background of the column headers to LightBlue while keeping the separators and sorting. Take a look at the default DataGridColumnHeader template in a template browser to see how to deal with modifying the Background when the mouse hovers over the ColumnHeader.
Hope this helps!