Reputation: 159
I have multiple DataGrids bound to DataTables, which are dynamically created using SQL. Whenever DataTable records change (add, modify, delete), the DataGridCells shall change their background color accordingly (green=new, yellow=modify etc.).
In WinForms I changed DataGridView's background color using _RowPostPaint (code is very simplified):
private void DataGridViewTest_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
{
DataRow row = (this.Rows[e.RowIndex].DataBoundItem as DataRowView).Row;
switch (row.RowState)
{
case DataRowState.Added:
myBitmap = new Bitmap(imageList.Images[1]);
this[0, e.RowIndex].Style.BackColor = CellChangesColorAdded;
break;
case DataRowState.Modified:
string sValOld = row[0, DataRowVersion.Original].ToString();
string sValNew = row[0].ToString();
if (sValOld != sValNew)
{
this[0, e.RowIndex].Style.BackColor = CellChangesColorMod;
}
break;
case DataRowState.Deleted:
this[0, e.RowIndex].Style.BackColor = CellChangesColorDel;
break;
}
}
I do not want to hardcode column dependencies in XAML as in countless examples like this as they are created at run time and I have many DataGrids in use.
Trying to use DataGrid_CellEditEnding fails, as it does not keep the changes upon sorting etc.:
XAML:
<Window.Resources>
<Style x:Key="MyStyle" TargetType="{x:Type DataGridCell}">
<Setter Property="Background" Value="Green" />
</Style>
</Window.Resources>
<DataGrid x:Name="dataGrid" Grid.Row="4" Grid.ColumnSpan="6"
ItemsSource="{Binding}"
>
</DataGrid>
.cs:
dataGrid.DataContext = dataTable.DefaultView; // Table filled by SQL query
dataGrid.CellEditEnding += dataGrid_CellEditEnding;
// Problem: Color changes disappear when user sorts DataGrid
private void dataGrid_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
{
if (e.EditAction == DataGridEditAction.Commit)
{
TextBox tb = e.EditingElement as TextBox;
DataGridCell cell = tb.Parent as DataGridCell;
// evaluate row changes and change color accordingly
//cell.Background = new SolidColorBrush(Colors.Yellow); // set style instead of color
cell.Style = (Style)this.Resources["MyStyle"]; // color is changed to green, according to defined style
}
}
This changes the background color perfectly fine, however the style is not being kept upon sorting the DataGrid etc.
How can I ensure color changes are being kept? In my opinion, the best solution would be to somehow bind DataRows to a helper class and return the respective style upon DataTable changes. However I haven't seen any example for that yet.
Upvotes: 1
Views: 12578
Reputation: 159
For completeness:
If you really intend to change the color at runtime, disregarding MVVM you can for instance use DataGrid_LoadingRow, check for it's DataContext (in this case a DataRowView) and go on from there:
// Changes beeing made to the entire row in this case
private void DgModules_LoadingRow(object sender, DataGridRowEventArgs e)
{
DataGridRow gridRow = e.Row;
DataRow row = (gridRow.DataContext as DataRowView).Row;
switch (row.RowState)
{
case DataRowState.Added:
gridRow.Background = new SolidColorBrush(Colors.Green);
break;
case DataRowState.Modified:
gridRow.Background = new SolidColorBrush(Colors.Yellow);
break;
case DataRowState.Deleted:
gridRow.Background = new SolidColorBrush(Colors.Red);
break;
}
}
If you wanna approach this actually using MVVM, go for this solution.
Upvotes: 3