1
votes

Say I have an ObservableCollection (type MyRow) (called Rows) of rows. In MyRow I have a bunch of properties, including an ObservableCollection (type MyRowContents) (called Contents) - which is basically a list of all of the contents that will be in that row. MyRowContents also has several properties, including DisplayContents (string).

For example... for DataGrid with 2 rows, and 3 columns the data structure would be 2 "Rows", and each would contain 3 "Contents".

What do I have to do in the DataGrid in the XAML so that the cell contents display Rows[i].Contents[j].DisplayContents?

EDIT:

Hi, sorry for not being clear enough in the initial message. I am trying to make a data grid that is capable of displaying data dynamically (from a database table that is unknown ahead of time).

I have used this as a guide: http://pjgcreations.blogspot.com.au/2012/09/wpf-mvvm-datagrid-column-collection.html - and I can display the columns dynamically.

    <DataGrid ItemsSource="{Binding Rows}" AutoGenerateColumns="False" 
              w:DataGridExtension.Columns="{Binding ElementName=LayoutRoot, Path=DataContext.Columns}" />

I just don't know how to display the row data dynamically.

MyRow is:

public class MyRow
{
    public int UniqueKey { get; set; }
    public ObservableCollection<MyRowContents> Contents { get; set; }
}

MyRowContents is:

public class MyRowContents
{
    public string ColumnName { get; set; } // Do I need this?
    public object DisplayContents { get; set; } // What I want displayed in the grid cell
}

I have a public property ObservableCollection Rows in my view model, which as you can see is what I am binding to in the ItemsSource. But I don't know how to get the "DisplayContents" of each MyRowContents to display in the appropriate cell in the grid view.

Given that I can display the column names dynamically, this assumption can be made: the order of the items in Contents (in MyRow) will match the order of the columns.

Thanks

1
I have edited your title. Please see, "Should questions include “tags” in their titles?", where the consensus is "no, they should not". - John Saunders
Can you post some code, the description is complex too like you class structure? - Rohit Vats
Yes, I have updated the initial message. Thanks. - theqs1000

1 Answers

2
votes

First of all you have to put row ID in RowContent so your app logic should be similar to:

RowContent.cs :

public class RowContent
{
    //public string ColumnName { get; set; } "you dont need this property."

    public int ID;  //You should put row ID here.
    public object DisplayContents { get; set; } "What is this property type, is string or int or custom enum??"
}

RowViewModel.cs :

public class RowViewModel
{
    public ObservableCollection<MyRowContents> Contents { get; set; }
}

Now you have to put your Collection in Window.DataContext to be able to bind it in DataGrid

MainWindow.xaml.cs :

public partial class MainWindow : Window
{
    private RowViewModel rvm = new RowViewModel(); //Here i have made new instance of RowViewModel, in your case you have to put your ViewModel instead of "new RowViewModel();";

    public MainWindow()
    {
        InitializeComponent();

        DataContext = rvm; // this is very important step.
    }
}

Last step is in window XAML.

MainWindow.xaml :

<DataGrid ItemsSource="{Binding Path=Contents}" AutoGenerateColumns="false">
    <DataGrid.Columns>
        <DataGridTextColumn Header="Row ID" Binding="{Binding Path=ID,UpdateSourceTrigger=PropertyChanged}"/>
        <DataGridTextColumn Header="your row header" Binding="{Binding Path=DisplayContents,UpdateSourceTrigger=PropertyChanged}"/>
    </DataGrid.Columns>
</DataGrid>

There is Five types of DataGridColumn, you have to select appropriate type depending on the type of DisplayContents property.