Quoting via WPF DataGrid Using foreach

That's it, I'm trying to execute a WPF DataGrid loop with a for each loop to change the background color of the error cells. I checked a lot of questions, but I still have to find a sufficient answer. What am i still

 public void RunChecks() { const int baseColumnCount = 3; foreach (DataRowView rv in dataGrid.Items) { for (int i = baseColumnCount; i < dataGrid.Columns.Count; i++) { if (!CheckForBalancedParentheses(rv.Row[i].ToString())) { Color color = (Color)ColorConverter.ConvertFromString("#FF0000"); row.Background = new SolidColorBrush(color); // Problem! } } } } 

The problem is that in order to change the Background color of the row in my DataGrid I need to work with the DataGridRow object associated with the DataRowView rv .

How to get a link to a DataGridRow from an rv ( DataRowView ) object?

Thank you for your time.

Change Based on the tip below, I now have the following style that works with the mouse on the event and sets the back and front fonts of the corresponding cell. However, I really lost how to apply inverse color to the cell at runtime in my code above. XML style

 <Window.Resources> <Style TargetType="{x:Type DataGridRow}"> <Style.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="Background" Value="Red" /> <Setter Property="FontWeight" Value="ExtraBold" /> </Trigger> </Style.Triggers> </Style> </Window.Resources> 
+6
source share
5 answers

When working with WPF, always avoid direct access to user interface artifacts.

Create a Color property in ModelView and bind it to the background color of the single row template of your DataGrid.

So, to change the color, you will drop the ModelView collection and set / read the Color property of each individual object bound to each individual row. By changing it, if the binding is correctly set, you will affect the appearance of the interface line.

For a specific sample, you can see:

How to associate the background of a row of a data grid with a specific color?

+5
source

You can use ItemContainerGenerator to get a visual representation for your data, i.e. DataGridRow -

 DataGridRow row = (DataGridRow)dataGrid.ItemContainerGenerator .ContainerFromItem(rv); 
+2
source

Killercam's answer worked for me, but I needed to add:

myDataGrid.UpdateLayout();

before using GetCell methods, so I'm sure I am not getting a null reference.

so that the entire Helper class looks at the DataGridHelper

after all this pain, I tried all the code, and I ran into another problem, which was that the correctly colored cells changed during scrolling, the solution was to enable virtualization and set its mode to standard.

 VirtualizingStackPanel.IsVirtualizing="True" VirtualizingStackPanel.VirtualizationMode="Standard" 

so hopefully this will help anyone who needs to iterate through the data cells.

+1
source

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); // Start work with cell. Color color; TextBlock tb = cell.Content as TextBlock; string cellValue = tb.Text; if (!CheckForBalancedParentheses(cellValue)) color = (Color)ColorConverter.ConvertFromString("#FF0000"); else color = (Color)ColorConverter.ConvertFromString("#FFFFFF"); row.Background = new SolidColorBrush(color); //cell.Background = new SolidColorBrush(color); } } } } 

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.

0
source
 //the Class that resembles the Datagrid Item schema foreach (Class cl in dgDatagrid.Items) { MessageBox.Show(cl.ID.ToString()); } this is the most simplest way to read the datagrid data most articles misguide such simple things 
0
source

All Articles