开发者

Seeking a more elegant method to populate a WPF DataGrid with dynamic columns (one column for each object's property)

开发者 https://www.devze.com 2023-04-08 09:01 出处:网络
I am trying to setup a WPF datagrid. The standard datagrid is setup to accept a list of objects which are displayed on different rows, with a column for each property. I actually need to do the invers

I am trying to setup a WPF datagrid. The standard datagrid is setup to accept a list of objects which are displayed on different rows, with a column for each property. I actually need to do the inverse; a row for each property, and a column for each object in the list. Therefore I started with the solution proposed by blindmeis here in order to handle a dynamic number of columns and it works well so far.

I have a class DataGridVM to which I can pass a list of objects. Each of the objects has its own View Model which derives from a class ParentalBaseVM. Each property of that object has its own View Model which derives from a class ElementVM.

Each ParentalBaseVM can return list of ElementVM for each of its object’s properties through overriding the virtual method PropertyLists E.g. within an example of a class dervived from ParentalBaseVM I have:

    public override Dictionary<string, List<ElementVM>> PropertyLists
    {
        get
        {
            Dictionary<string, List<ElementVM>> iPropertyLists = new Dictionary<string, List<ElementVM>>();
            List<ElementVM> BasicProperties = new List<ElementVM>();
            BasicProperties.Add(iNBViewModel);
            BasicProperties.Add(iIDViewModel);
            iPropertyLists.Add("Basic", BasicProperties);
            List<ElementVM> AdvancedProperties = new List<ElementVM>();
            AdvancedProperties.Add(iNBViewModel);
            AdvancedProperties.Add(iIDViewModel);
            AdvancedProperties.Add(iXSAreaViewModel);
            iPropertyLists.Add("Advanced", AdvancedProperties);
            return iPropertyLists;
        }
        set
        {
        }
    }

As you can see, I can return a different set of properties by passing either “Basic” or “Advanced” as a string.

The DataGridVM code is below. I pass to this the list of objects (columnList) and the string which represents the (“Basic” or “Advanced” in the example above)

class DataGridVM
{
    private List<List<ElementVM>> iDataList;
    public DataGridVM(List<ParentalBaseVM> columnList, string rowListKey)
    {
        iDataList = new List<List<ElementVM>>();
        for (int i = 0; i < columnList[0].PropertyLists[rowListKey].Count; i++)
        {
            List<ElementVM> newRowList = new List<ElementVM>();
            for (int j = 0; j < columnList.Count; j++)
            {
                newRowList.Add(columnList[j].PropertyLists[rowListKey][i]);
            }
            iDataList.Add(newRowList);
        }
    }
    public List<List<ElementVM>> DataList
    {
        get
        {
            return iDataList;
        }
        set
        {
        }
    }
}

Finally, the datagrid is populated using:

testControlDataGrid.testDataGrid.ItemsSource = testDataGridVM.DataList;

And then the columns are generated dynamically (the code within CreateDataTemplate sets up the bindings)

for (int i = 0; i < testDataGridVM.DataList[0].Count; i++)
        {

            testControlDataGrid.testDataGrid.Columns.Add(new DataGridTemplateColumn()
            {
                Header = "Col" + i,
                CellTemplate = CreateDataTemplate(TheTextBlock.GetType(),i)
            });
        }

This all works fine, but it feels very messy. Passing string values like “Basic” and accessing dictionaries feels wrong. Perhaps there is an elegant solution where I have classes deriving from DataGridVM such as DataGridVMBasicProperties which accesses the “Basic” properties of the object, but I’m not sure if this would result in repeating lots and lots of code.

Also, I’m not sure cluttering up the ParentalBaseVM class with a method which returns the list of properties is great either. I was thinking of pe开发者_运维问答rhaps moving this to a new base class PropertiesListGenerator which can simply have a ParentalBaseVM passed to it, and returns a list of ElementVM. A derivation could be BasicPropertiesListGenerator, and a further derivation of this could be AdvancedPropertiesListGenerator. However, if not all ParentalBaseVM contain an "advanced" list and only the "basic" list then this may cause problems. My main aim here is to avoid repeating lots of code.

I have never used Delegates or Interfaces enough to truly understand them, so my coding skills aren’t really firing on all cylinders. Maybe they can help provide an elegant solution?

Any help is appreciated. I’m new to this and programming isn’t my full time job (evidently). If you see room for improvement in layout, readability, convention following, please feel free to suggest, I certainly will not be offended.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号