After long readings, I found a way to do what I wanted - colored cells at runtime depending on certain conditions. This is the method I use for coloring.
public void RunChecks() { const int baseColumnCount = 3; for (int i = baseColumnCount; i < dataGrid.Columns.Count; i++) { foreach (DataGridRow row in Utilities.GetDataGridRows(dataGrid)) { if (row != null) { DataGridCell cell = dataGrid.GetCell(row, i);
These are utility methods associated with them.
public static T GetVisualChild<T>(Visual parent) where T : Visual { T child = default(T); int numVisuals = VisualTreeHelper.GetChildrenCount(parent); for (int i = 0; i < numVisuals; i++) { Visual v = (Visual)VisualTreeHelper.GetChild(parent, i); child = v as T; if (child == null) child = GetVisualChild<T>(v); if (child != null) break; } return child; } public static DataGridCell GetCell(this DataGrid grid, DataGridRow row, int column) { if (row != null) { DataGridCellsPresenter presenter = GetVisualChild<DataGridCellsPresenter>(row); if (presenter == null) { grid.ScrollIntoView(row, grid.Columns[column]); presenter = GetVisualChild<DataGridCellsPresenter>(row); } DataGridCell cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(column); return cell; } return null; } public static IEnumerable<DataGridRow> GetDataGridRows(DataGrid grid) { var itemsSource = grid.ItemsSource as IEnumerable; if (null == itemsSource) yield return null; foreach (var item in itemsSource) { var row = grid.ItemContainerGenerator.ContainerFromItem(item) as DataGridRow; if (null != row) yield return row; } }
Note, however, that the color of the cells moves from cell to cell when the user scrolls !? This is another surprising annoyance of WPF. I am really confused why something so simple can be made so complicated. The suggestion that we need to use a MVVM type template for this kind of thing, I find it amazing ...
I hope this helps someone else.
source share