There have been several questions on the WPF CodePlex discussion list relating to styling rows and columns based some requirements on other elements or some other conditions. I decided to put a couple examples here on different ways you can accomplish this.
Adding a trigger to a CellStyle based on a column condition
From a DataGridCell, you can access the column that it belongs to through DataGridCell.Column. With that you set a trigger based on a DataGridColumn property or a derived DataGridColumn property. Here is an example of a trigger that sets the background of a DataGridCell to LightGray of the column is frozen.
Updating CellStyle based on a condition in the column header
From a DataGridColumnHeader, you have access to the column through DataGridColumnHeader.Column. This gives you access to all the DPs on the DataGridColumn which includes DataGridColumn.CellStyle. With that you can update the CellStyle based on some condition that you set. Let’s say I have a checkbox in the DataGridColumnHeader template and when checked I want to highlight the entire column. Here is a possible solution:
With the CellBackgroundConverter I can choose a particular CellStyle based on the IsChecked property. Each CellStyle would set the background to a different value.
Updating cell properties based on a condition in a derived column
An alternative to the converter example above is to update cell properties based on a derived DataGridColumn condition that you create. Let’s say I create a custom column that derives from DataGridColumn and has a property called IsHighlighted. I want to use the CheckBox in my DataGridColumnHeader to highlight the column like before. Since the DataGridColumnHeader has access to the DataGridColumn, you can also set bindings on derived DataGridColumn properties. From the DataGridColumnHeader, I can bind that CheckBox to the IsHighlighted property and use that to highlight the column instead of a converter. Here is an example:
I set the Mode to OneWayToSource as I only care that local:CustomColumn.IsHighlighted is updated which I mark the CheckBox as checked. With that I can use a trigger in the DataGridCell based on the derived column property.
Updating RowStyle based on a condition from the row header
From a DataGridRowHeader, you have direct access to the DataGridRow as it is an ancestor in the visual tree. So all you need to do is find the DataGridRow and update its style. Here is an example which is similar to the CellStyle example:
Since I have direct access to the DataGridRow, I can set the Path directly on Background if I wanted to. However, I wanted to update a couple properties so I update the Style instead.
Caveat: One thing to note about doing this however is item container recycling. If you leave it on you will see some side effects. Basically as you scroll rows in and out of view they will lose the checked state. Ways you can avoid this is either to turn recycling off or keeping state yourself and overriding the ItemsControl.PrepareContainerForItemOverride to update the row.
Updating cell properties based on Database related properties
Let’s say that you want to signal that a column is the primary key or allows null values or is a particular value type. For the signal, I will set the cell backgrounds like I have been in previous examples. Since the cell has access to the DataGridColumn, I can create a derived property on the DataGridColumn and bind to that in the DataGridCell’s Style:
Setting up the binding is a little tricky however. I decided to set the property directly in the AutoGeneratingColumn event. For a non-auto-generating scenario you would need a converter on the binding to IsPrimaryKey to find the correct source to bind to. Anyway, for the auto-generating scenario, I copy the properties from DataGridColumn to set to my CustomColumn then search the MetaTable to find if the column is a primary key (I’m using linq to sql in this example).
The full solution of examples is attached.
More Related Material:
Other DataGrid Samples: