Shinva
Shinva

Reputation: 2302

WPF Datagrid - Autogenerate columns based on a DataTable of objects and set backgroud color

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.

Upvotes: 0

Views: 1828

Answers (2)

mm8
mm8

Reputation: 169390

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.

Upvotes: 0

Roger Leblanc
Roger Leblanc

Reputation: 1583

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>

Upvotes: 1

Related Questions