Dynamically creating GridView from an ObservableCollection

74 views Asked by At

In my C# / WPF application, I have a ListView that I want to use as a GridView to display items in a table:

<ListView x:Name="Table_ListView" ItemsSource="{Binding Conditions}"/>

It is binded to a ObservableCollection<Condition>, where Condition is defined like this:

public class Condition
{
    public string Name { get; set; }
    public ObservableCollection<Property> Properties { get; set; }

    public class Property
    {
        public string Name { get; set; }
        public double Value { get; set; }
    }
}

(Please note that I skipped INotifyPropertyChanged implementation here to simplify this example code).

Idea is that GridView Column headers should display Name property of instances of Condition, while row headers should display Name instance of Property, and the cells - the Value. It is expected that all Condition instances will have the same number of Property instances with the same names. So for example if we have this method that creates sample data:

private ObservableCollection<Condition> CreateConditions()
{
    ObservableCollection<Condition> conditions = new();

    conditions.Add(
    new Condition()
    {
        Name = "c1",
        Properties = new() 
        {
            new() { Name = "p1", Value = 5 },
            new() { Name = "p2", Value = 10 },
            new() { Name = "p3", Value = 15 },
        }
    });

    conditions.Add(
    new Condition()
    {
        Name = "c2",
        Properties = new()
        {
            new() { Name = "p1", Value = 8 },
            new() { Name = "p2", Value = 12 },
            new() { Name = "p3", Value = 20 },
        }
    });

    conditions.Add(
    new Condition()
    {
        Name = "c3",
        Properties = new()
        {
            new() { Name = "p1", Value = 11 },
            new() { Name = "p2", Value = 17 },
            new() { Name = "p3", Value = 25 },
        }
    });

    return conditions;
}

Then the GridView table should look like this:

-   c1  c2  c3
p1  5   8   11
p2  10  12  17
p3  15  20  25

Since I'm trying to use MVVM, the view model looks like this:

public class TableResultsViewViewModel
{
    public ObservableCollection<Condition> Conditions { get; set; }

    public TableResultsViewViewModel(ObservableCollection<Condition> conditions)
    {
        this.Conditions = conditions;
    }
}

And the main class:

public partial class MainWindow : Window
{
    private TableResultsViewViewModel vm;

    public MainWindow()
    {
        InitializeComponent();
        ObservableCollection<Condition> conditions = CreateConditions(); //sample data creation method from before
        vm = new TableResultsViewViewModel(conditions);
        this.DataContext = vm;
    }
}

But I can't figure out how to properly declare the ListView in WPF so that it would dynamically generate these columns and rows as the ObservableCollection<Condition> Conditions changes (instances of Condition added or removed from this collection, or instances of Property added or removed from Properties list inside the instances of Condition). Has anyone done anything similar and could help me out?

EDIT: I am not particularly bound to use ListView/GridView. DataGrid is also acceptable. I just used GridView in my current attempt.

0

There are 0 answers