mauryat
mauryat

Reputation: 1646

Binding DataGrid to Collection<List>

Can a DataGrid be bound to a Collection<List> type?

There are several questions on binding a DataGrid to a Collection<Collection> and it sort of worked for me too. But, I am looking specifically for DataGrid <-- Binding --> Collection<List>.


When I tried, the List is just getting displayed as an object on the DataGrid like:

Name
- System.Collections.Generic.List'1[System.Int32]
Value
Bob
23
43000
+ System.Collections.Generic.List'1[System.Int32]


How is a List different from a Collection in this case?

A List doesn't have identifiers for entries and hence entries in a List cannot be automatically grouped into columns in a DataGrid.

Example:

In Collection<List>:
entry1 contains the List: "Bob", 23, 43000 and
entry2 contains the List: "Alice", 42, 71000.

Will I be able to use a DataTemplate for a List to get the following display?
Name | Age | Salary
Bob | 23 | 43000
Alice | 42 | 71000

Notice that strings Name, Age and Salary aren't part of the Lists.


My plan

  1. Bind the header row to a List<String> to get the column names in the DataGrid's header.
  2. Bind the remaining rows to Collection<List> to get the data populated in the DataGrid.

Specifially, I'm wondering if I can put these 3 strings (Name, Age, Salary) in a List<String> and bind only the header row to it. The remaining rows of the DataGrid can be bound to Collection.

Is this even possible?


Ideally, I would like to use Infragistics' XamDataGrid, but any solution to DataGrid will be a good starting point.


EDIT

Why don't I use Collection<Employee>? I would like to display only a subset of columns in the DataGrid.

I have about 5 screens which display columns from 2 types Employee and EmployeeDetails. Both these types have about 100 different properties each and I'm only interested in displaying about 20 properties as columns on each screen. Hence, I'm creating a List for each Employee/EmployeeDetails object that contains only these 20 properties.

The subset is defined at run-time by reading some config files. Hence, I can't statically define what I need to show.

Upvotes: 1

Views: 1537

Answers (2)

ken2k
ken2k

Reputation: 48975

You could use a binding converter to extract a member of your list:

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
    if (value is List<string> && parameter is int)
    {
        return ((List<string>)value)[(int)parameter];
    }

    return null;
}

... but honestly I don't understand what you're trying to achieve. Your list of strings represents the properties of an object, why don't just use a Collection<Employee> where Employee is

public class Employee : INotifyPropertyChanged
{
    public string Bob
    {
        ...
    }

    public int Age
    {
        ...
    }

    public double Salary
    {
        ...
    }
}

Strongly typed, much more readable, much more maintainable.


EDIT:

After reading your edit: definitely don't use a List<string>. Simply do not ask your XamDataGrid to automatically generate a column for each field. You've also some examples about how to hide columns.


EDIT:

It's way much more MVVM friendly to expose a Collection<Employee> property + write some code behind, than to expose Collection<List<string>>.

Remember the limitations of the XamDataGrid control are purely related to the view part of the MVVM pattern. Don't change the ViewModel logic because of that.

Also here's a related question that could help: XamDataGrid column visibilty is not working using MVVM

Upvotes: 2

Josh
Josh

Reputation: 10604

This doesn't sound right. The items that you show inside the Collection are just objects with properties. Why not just have a collection of objects with those properties?

In order to iterate the second list, you would need another ItemsControl inside the bound row bound to that list as its data source. Otherwise, you will always just receive the System.Collections.Generic.List'1[System.Int32] binding value because that is the current level of what is being iterated.

If you wanted to keep it generic, you could even bind to a Collection, allowing the object to define its properties and in the Datagrid, only binding to the properties that it thinks should be visible (whether or not the object supports that).

Upvotes: 1

Related Questions