Create a class that will describe the cell:
class Cell { public string Value { get; } public string Color { get; } public Cell(string value, string color) { Value = value; Color = color; } }
Create a class that will describe the string:
class Row { public Cell Column1 { get; } public Cell Column2 { get; } public Cell Column3 { get; } public Row(Cell column1, Cell column2, Cell column3) { Column1 = column1; Column2 = column2; Column3 = column3; } }
Get a collection of strings and write data from the DataTable into it:
public List<Row> Table { get; } Конструктор { var values = dataTable.Rows[0].ItemArray; var colors = dataTable.Rows[1].ItemArray; Table = new List<Row>(); Table.Add ( new Row ( new Cell((string)values[0], (string)colors[0]), new Cell((string)values[1], (string)colors[1]), new Cell((string)values[2], (string)colors[2]) ) ); }
Markup DataGrid:
<DataGrid ItemsSource="{Binding Table}" AutoGenerateColumns="False"> <DataGrid.Columns> <DataGridTextColumn Header="заголовок 1" Binding="{Binding Column1.Value}"> <DataGridTextColumn.CellStyle> <Style TargetType="DataGridCell"> <Setter Property="Background" Value="{Binding Column1.Color}"/> </Style> </DataGridTextColumn.CellStyle> </DataGridTextColumn> <DataGridTextColumn Header="заголовок 2" Binding="{Binding Column2.Value}"> <DataGridTextColumn.CellStyle> <Style TargetType="DataGridCell"> <Setter Property="Background" Value="{Binding Column2.Color}"/> </Style> </DataGridTextColumn.CellStyle> </DataGridTextColumn> <DataGridTextColumn Header="заголовок 3" Binding="{Binding Column3.Value}"> <DataGridTextColumn.CellStyle> <Style TargetType="DataGridCell"> <Setter Property="Background" Value="{Binding Column3.Color}"/> </Style> </DataGridTextColumn.CellStyle> </DataGridTextColumn> </DataGrid.Columns> </DataGrid>
Result:

Solution tied to DataTable (thanks for the help @VladD).
The Cell class shown above is used, we convert the input DataTable with string to Datatable with Cell :
public DataTable Table { get; } конструктор { ... Table = new DataTable(); foreach (DataColumn column in InputTable.Columns) Table.Columns.Add(column); for (int i = 0; i < InputTable.Rows.Count / 2; ++i) { var values = InputTable.Rows[2 * i].ItemArray; var colors = InputTable.Rows[2 * i + 1].ItemArray; Table.Rows.Add(values.Zip(colors, (v, c) => new Cell((string)v, (string)c)).ToArray()); } }
Still need a converter:
public class DataRowViewConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (value is DataGridCell cell && cell.DataContext is DataRowView drv) return drv.Row[cell.Column.SortMemberPath]; else return null; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); } }
Now the markup:
<DataGrid ItemsSource="{Binding Table}" AutoGeneratingColumn="OnAutoGeneratingColumn"> <DataGrid.Resources> <local:DataRowViewConverter x:Key="drvc"/> </DataGrid.Resources> <DataGrid.CellStyle> <Style TargetType="DataGridCell"> <Setter Property="Tag" Value="{Binding RelativeSource={RelativeSource Self}, Converter={StaticResource drvc}}"/> <Setter Property="Background" Value="{Binding Tag.Color, RelativeSource={RelativeSource Self}}"/> </Style> </DataGrid.CellStyle> </DataGrid>
and subscriber in CodeBehind:
void OnAutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e) { var column = (DataGridTextColumn)e.Column; column.Binding = new Binding { Path = new PropertyPath(nameof(FrameworkElement.Tag) + "." + nameof(Cell.Value)), RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, typeof(DataGridCell), 1) }; column.SortMemberPath = e.PropertyName; column.IsReadOnly = true; }
A bit complicated, but this is the DataGrid .
If you want to edit the values, then the installation of IsReadOnly needs to be removed, but do not forget then add the setter to Cell.Value