Alteração do estilo da célula WPF DataGrid após atualização
-
21-12-2019 - |
Pergunta
Tenho um DataGrid com colunas geradas dinamicamente e preciso alterar o estilo das células cujos valores foram alterados após algumas manipulações.
O ItemsSource para DataGrid é definido como List<MyTableRow>
, onde
public class MyTableRow
{
private string[] _values;
private string _rowHeader;
// getters and setters here
}
As colunas DataGrid são geradas com o seguinte código:
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];
}
O DataGrid resultante se parece com esse
O problema surge quando tento destacar (texto em negrito ou fundo colorido) células cujos valores em ItemsSource foram alterados.Este é o ponto em que minha pergunta se divide em duas:
- Existe alguma maneira "integrada" de fazer algo com células alteradas?(talvez com
ObservableColletion
ou algo mais) - Se não, como posso destacar células separadas com base em seus índices ou valores?
Tentei fazer isso com estilos xaml e/ou gatilhos, mas descobri que não sei qual valor de cegamento devo passar para o conversor
<Style TargetType="TextBlock">
<Setter Property="Background"
Value="{Binding <!-- some proper binding here -->,
Converter={StaticResource ValueToBrushConverter}}"/>
</Style>
Outras soluções encontradas no SO têm o mesmo "problema" de ligação ou simplesmente não funcionam.O que posso fazer para destacar apenas um célula e não linha/coluna inteira?Posso alterar ItemsSource, MyTableRow
código de geração de campos e/ou colunas, se necessário
Alguém por favor pode me ajudar?Já faz alguns dias que não tive esse problema
ATUALIZAR Solução encontrada
Solução
Finalmente descobrir como fazer o que eu quero.A solução é meio "suja", mas funciona bem para mim.Adicionei um caractere de espaço ininterrupto a cada célula que preciso destacar
private const string NBSP = "\u00A0"
Depois disso, tudo o que resta fazer é criar um conversor de valor.Então eu adicionei MultiBinding
no meu 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 definido como:
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();
}
}
Espero que isso ajude alguém!