4
votes

I'm developing a WPF app based on MVVM. I want to bind a list of strings to column header ie., if the list contains "abc", "xyz", "pqr", then my DataGrid should have three columns with header abc, xyz, pqr. Here is my class to which I am binding the datagrid. The rows are stored in ObservableCollection<List<string>> where each element of ObservableCollection is a List of string which forms the cells of the rows.

public class Resource
{
    private ObservableCollection<string> columns;
    public ObservableCollection<string> Columns
    {
        get
        {
            return columns;
        }
        set
        {
            columns = value;
        }

    }

    private ObservableCollection<List<string>> row;
    public ObservableCollection<List<string>> Row
    {
        get
        {
            return row;
        }
        set
        {
            row = value;
        }
    }

    public Resource()
    {
        List<string> a = new List<string>();
        a.Add("1");
        a.Add("2");
        List<string> b = new List<string>();
        b.Add("11");
        b.Add("21");
        Row = new ObservableCollection<List<string>>();
        Row.Add(a);
        Row.Add(b);

        Columns = new ObservableCollection<string>();
        Columns.Add("Hello");
        Columns.Add("World");
    }
}

I have searched Internet a lot but couldn't find anything with a working example. I really need to bind DataGrid by this method only.

1
Do you want to be able to reorder the columns?Markus
@Markus I need to sort per column but not reorderAbhishek Batra
In my experience, even though it is doable using attached properties, this approach is too cumbersome and too limiting, and forces you to move to procedural code UI-specific things that should really be done in XAML. Use a specific XAML-defined DataTemplate per data-type instead of trying a "one size fits all" solution that won't really be suitable for anything but the very basic string-only data types.Federico Berasategui

1 Answers

4
votes

You can use the DataGrid in one of two ways :

1) Bind the DataGrid's ItemsSource to a Collection of elements which Expose 3 properties abc , xyz , pqr.

CS :

    public List<MyDataItem> DataItems 
    {
        get
        {
            List<MyDataItem> items = new List<MyDataItem>(5);

            for (int i = 0; i < 5; i++)
            {
                items.Add(new MyDataItem { abc = abc[i], qrt = qrt[i], xyz = xyz[i] });
            }

            return items;
        }
    }

    int[] abc = new int[5] { 1, 2, 3, 4, 5 };
    int[] qrt = new int[5] { 6,7,8,9,10 };
    int[] xyz = new int[5] { 11,12,13,14,15};


    public event PropertyChangedEventHandler PropertyChanged = delegate { };

}

public class MyDataItem
{
    public int abc { get; set; }
    public int qrt { get; set; }
    public int xyz { get; set; }
}

XAML :

 <DataGrid ItemsSource="{Binding DataItems}" />    

2) Create a DataTable object and Bind it to your ItemsSource.

 public DataTable DataTable
    {
        get
        {
            DataTable table = new DataTable();

            table.Columns.Add("abc");
            table.Columns.Add("qrt");
            table.Columns.Add("xyz");

            table.Rows.Add(1, 6, 11);
            table.Rows.Add(2, 7, 12);
            table.Rows.Add(3, 8, 13);
            table.Rows.Add(4, 9, 14);
            table.Rows.Add(5, 10, 15);

            return table;
        }
    }