I have a DataGrid with dynamicaly generated columns and I need to change style of cells whose values have changed after some manipulations.
The ItemsSource for DataGrid is defined as List<MyTableRow>
, where
public class MyTableRow
{
private string[] _values;
private string _rowHeader;
// getters and setters here
}
DataGrid columns are generated with following code:
for (int i = 0; i < source[0].Values.Length; i++)
{
var col = new DataGridTextColumn();
var binding = new Binding("Values[" + i + "]");
col.Binding = binding;
col.CanUserSort = false;
this.dataGrid.Columns.Add(col);
this.dataGrid.Columns[i].Header = columnNames[i];
}
Resulting DataGrid looks like this
The problem arises when I try to highlight (bold text or colored background) cells whose values in ItemsSource have changed. This i sthe point where my question splits into two:
ObservableColletion
or smth else) I tried to do this with xaml styles and/or triggers, but it turned out that i do not know what value blinding should I pass to converter
<Style TargetType="TextBlock">
<Setter Property="Background"
Value="{Binding <!-- some proper binding here -->,
Converter={StaticResource ValueToBrushConverter}}"/>
</Style>
Other solutions found on SO either have the same "problem" with binding or just don't work. What can I do to highlight just one cell and not whole row/column? I can change ItemsSource, MyTableRow
fields and/or columns' generation code, if necessary
Can anyone please help me out? Been a few days since I stuck with this problem
UPDATE Found solution
Finally find out how to do what I want. The solution is kinda "dirty", but works fine for me. I added non-breaking space character to every cell I need to highlight
private const string NBSP = "\u00A0"
All that's left to do after that is to create value converter. So I added MultiBinding
in my XAML:
<DataGrid.CellStyle>
<Style TargetType="{x:Type DataGridCell}">
<Setter Property="Background">
<Setter.Value>
<MultiBinding Converter="{StaticResource ValueToBrushMultiConverter}" >
<MultiBinding.Bindings>
<Binding RelativeSource="{RelativeSource Self}" />
<Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type DataGridRow}}" />
</MultiBinding.Bindings>
</MultiBinding
</Setter.Value>
</Setter>
</Style>
</DataGrid.CellStyle>
Сonverter defined as:
public class ValueToBrushMultiConverter : IMultiValueConverter
{
private const string NBSP = "\u00A0";
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var cell = (DataGridCell)values[0];
var dgRow = (DataGridRow)values[1];
var test = (dgRow.Item as TableRow<string, string>).Values[cell.Column.DisplayIndex];
if (test.Contains(NBSP))
return System.Windows.Media.Brushes.PaleGreen;
return DependencyProperty.UnsetValue;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotSupportedException();
}
}
Hope this helps someone!