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:

  1. Existe alguma maneira "integrada" de fazer algo com células alteradas?(talvez com ObservableColletion ou algo mais)
  2. 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


Foi útil?

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!

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top