0
votes

As part of my data processing I generate a DataTable(column count and row count vary) of the following class

public class DataGridCell
{
    public string Text { get; set; }
    public string Background { get; set; }
}

My plan is to bind a DataGrid to this DataTable; each cell should display the DataGridCell.Text value and the background color of that cell should be the DataGridCell.Background value.

I have tired the following

C#

DataTable dtVolume = new DataTable();
    for (int i = 0; i < ColumnNames.Length; i++)
    {
        dtVolume.Columns.Add(ColumnNames[i]);
    }
    for (double p = max; p > min; p -= 0.05)
    {
        var row = dtVolume.NewRow();
        for (int i = 0; i < ColumnNames.Length; i++)
        {
            row[i] = new DataGridCell
            {
                Text = i,
                Background = i % 2 == 0 ? "LightGray" : "Red"
            };
        }
        dtVolume.Rows.Add(row);
    }

dgVolumes.DataContext = dtVolume.DefaultView;

XAML

<DataGrid  x:Name="dgVolumes" ItemsSource="{Binding}">
<DataGrid.CellStyle>
    <Style TargetType="DataGridCell">
        <Setter Property="Background" Value="LightGray"/>
    </Style>
</DataGrid.CellStyle>

This gives me a DataGrid with the cells background set to LightGray but the text displayed is Namespace.DataGridCell

The XAML below errors out as {Binding Path=Background} fails as the context is a DataRowView

XAML

<DataGrid  x:Name="dgVolumes" ItemsSource="{Binding}">
<DataGrid.CellStyle>
    <Style TargetType="DataGridCell">
        <Setter Property="Background" Value="{Binding Path=Background}"/>
    </Style>
</DataGrid.CellStyle>

How do I do this ?

The solution provided here WPF Binding to a DataGrid from a DataTable of Objects and another at Change DataGrid cell colour based on values does not AutoGenerate the columns. They use DataGridTemplateColumn but in my case the columns need to be auto-generated as the number of columns (and rows) will change.

2
How exactly are you "generating" the DataTable? You need to post this code if you want anyone to be able to tell you what you are doing wrong.mm8
Something similar to DataTable dtVolume = new DataTable(); for (int i = 0; i < ColumnNames.Length; i++) { dtVolume.Columns.Add(ColumnNames[i]); } for (double p = max; p > min; p -= 0.05) { var row = dtVolume.NewRow(); for (int i = 0; i < ColumnNames.Length; i++) { row[i] = new DataGridCell{ Text = i, Background = i % 2 == 0 ? "LightGray" : "Red" } } dtVolume.Rows.Add(row); }Shinva
You'r approach won't work. See my answer.mm8

2 Answers

1
votes

What is dtVolume.DefaultView?

Using a standard binding works correctly, so I'm wondering what kind of object you're trying to bind your DataGrid to.

Here's the code I've used, let me know what's different on your side.

ViewModel and cs code :

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        DataContext = new MyViewModel();
    }
}

public class MyViewModel
{
    public MyViewModel()
    {
        Items = new List<DataGridCell>();
        for (int i = 0; i < 10; i++)
        {
            int c = i % 8;
            Items.Add(new DataGridCell
            {
                Text = $"Item #{i}",
                Background = $"#{c}{c}{c}{c}{c}{c}"
            });
        }
    }

    public List<DataGridCell> Items { get; set; }
}

public class DataGridCell
{
    public string Text { get; set; }
    public string Background { get; set; }
}

XAML code :

<Grid>
    <DataGrid  x:Name="dgVolumes" ItemsSource="{Binding Items}">
        <DataGrid.CellStyle>
            <Style TargetType="DataGridCell">
                <Setter Property="Background" Value="{Binding Background}"/>
            </Style>
        </DataGrid.CellStyle>
    </DataGrid>
</Grid>
0
votes

You can't really store the DataGridCell object in the DataRow. Please refer to my answer here for more information about this:

Binding an object to data grid cell - conditional cell style

Mixing an object model with a DataTable like this is not a good idea. Bind to either an IEnumerable<DataGridCell> or a DataTable with simple scalar column values.