All, I have an View model that is bound to a DataGrid
using MVVM.
<DataGrid ItemsSource="{Binding Path=Resources}">...</DataGrid>
Where
public ObservableCollection<ResourceViewModel> Resources { get; private set; }
in the ResourceViewModel
class I have the following properties
public string ResourceName
{
get { return this.resource.ResourceName; }
set {
...
}
}
public ObservableCollection<string> ResourceStringList
{
get { return this.resource.ResourceStringList; }
set {
...
}
}
All properties are displayed in the DataGrid
but the ResourceStringList
colletion is being displayed as '(Collection)'.
How can I get the DataGrid
to display each of the strings contained in the ResourceStringList
in its own column?
Thanks very much for your time.
Edit. I have implemented the suggestion by @Marc below. I now have the following screenshot to illustrate what I now require:
The blank column before my resources column index 3 (zero indexed) is not required, how do I remove this column?.
I would also like to know how to add column names to my resource columns? Perhaps I can just add a Binding
to Header
property of the SeedColumn
.
Again thanks for your time.
I don't think there is a out of the box solution for your problem and your grid columns will have to be created manually. In my case I do it when my
DataGrid
is loaded. I worked on assumption that number of columns is fixed for each element, 10 in my example, and that they are in correct order:here is some simple example on Dropbox
A datagrid is usually used to display a list of items of the same type with a fixed set of properties per item where each column is one property. So each row is one item, each column is one property on the item. You're case is different, as there is no fixed set of properties but a collection you want to show as if it were a fixed set of a number of properties.
The way to go greatly depends on whether you only want to display the data or whether you want to allow the user to manipulate the data. While the first can be achieved relatively easy using value converters, the latter requires a little more coding to extend the DataGrid class to allow for this behavior. The solutions I show are two of a thousand possibilities and probably not the most elegant ones. That being said, I will describe both ways and start with the two-way version.
TWO-WAY BINDING (ALLOWS EDITING)
The sample project (100KB)
I created a custom
DataGrid
and a custom 'DataGridColumn', called 'SeedColumn'.SeedColumn
works just as a textcolumn, but has a propertyCollectionName
. TheDataGrid
will add one new text column per item in the collection you've specified inCollectionName
on the right hand side of the seed column. The seed column only works as a kind of placeholder to tell the DataGrid where to insert which columns. You could use multiple Seedcolumns in one grid.The Grid and the column classes:
The usage:
and the ViewModels I've used for testing:
and the look (old version without headers):
ONE-WAY BINDING (NO EDITING OF THE DATA)
A straight-forward way is to implement a converter which formats your data in a table and returns a view on this table to which the DataGrid can be bound. The disadvantage: It does not allow editing the strings, because once the table is created from the original data source, no logical connection between the displayed data and the original data exists. Still, changes on the collection are reflected in the UI, as WPF performs the conversion every time the data source changes. In short: This solution is perfectly fine if you only want to display the data.
How does it work
IValueConverter
ItemsSource
with this converterThis is how it would look like (my IDE is StackOverflow, so please check and correct, if necessary):
Then define a resource in your XAML like this, where loc is your namespace:
and then use it like this: