Here is a rephrased version of my issue:
Here is a screenshot of the result I'm looking for (from an older, non C#/WPF version of the application):
Looks like all the other grid-tree-views and what ObjectListView provides. But unfortunately I have some rules I have to follow:
WPF
MVVM
Just a DataGrid and its components must be used (no TreeView, ListView, etc.)
The Items are hold in an ObservableCollection<T> where T.Property1, T.Property2 etc hold the data for the columns of the DataGrid.
The lower Levels of an item are hold in T.PropertyChilds of type ObservableCollection<T> and are not known/filled beforehand. They must be loaded on the first exand of the item.
Here is a screenshot of similar data and what I've got so far in WPF/C#:
It looks like a standard DataGrid. But which columns it can hold, which property of T the columns are showing, which columns are currently visible, etc is defined by a own framework around the DataGrid which basically just adds columns to the public ObservableCollection<DataGridColumn> Columns Collection of a System.Windows.Controls.DataGrid.
My task is now to do a new class derived from DataGridColumn which can display and load the hierarchical data structure of my ViewModel described above.
The main problems I'm facing are as far as I can tell:
- how to visibly display the levels like a treeview in a DataGrid column
- how to process the loaded data from childs so they are shown as in the first screenshot above. Do I have to do a flat ObservableCollection<T> where I add the loaded ChildData and some extra properties like level and parent - or is it possible to define a kindo of a hierarchical data template for a DataGrid?
Thanks a lot
Soko
So I need to display a DataGrid in WPF. I'm using RadGridView from Telerik and Caliburn.Micro framework using the MVVM strategy.
In my presentation there are differing number of columns, X+2 to be exact as there is always a Label column and a Total column and then X number of others that hold a decimal number.
I do know the number at runtime before I create the classes I need so that could help.
So I'm currently considering a few methods of doing this but some of them have drawbacks so I would love if someone could point me towards a solution.
Create a ViewModel class for each row and for each Cell. The X number will be a collection and binding to it is problematic. I would need to customize the RadGridView itsefl to actually manage this.
Create a DataTable an the run and bind to it. I haven't managed to make this work and not sure if RadGridView actually supports DataTable. This will also not allow me to keep metadata for each cell, something I need to be easily able to update the cells because column + row aren't the only distinguishing keys I need.
Somehow dynamically create a object with x+2 properties to bind to.
Are there any solutions, guides or something out there to help me here?
I was wondering what the best way was to create an empty datagrid.
For example after you have hit new in excel, You have a grid with empty rows and columns.
I am using c# with WPF and .net 4.0.
Thank you.
As the comments have suggested, a datagrid is not a spreadsheet, but a method to display / edit existing data. That said if you want something similar, feel free to populate a collection with default / 'empty' objects and bind that to your grid. It just means that after working with the data, you will have to define a method to capture only the edited rows. This still means that the column-bound properties of your class need to be known ahead of time.
A DataGrid is used to display a collection. If you want to create an individual row DataGrid is not really the right tool. You could but a single empty row in the DataGrid using a collection of only on row. There is a lot of guidance on Master Detail on MSDN. If you don't know how many columns at design time you could used a DataGrid to turn the row vertical with column 1 as name and column as value so now you have one record but with a collection of fields.
I have a list of string array as input. The array dimension are static for all the list but I can't know the array size until the list is retrieved.
I need to bind the list in a datagrid in Silverlight.
I tried to create columns at runtime, binding each column to a particular array position but cannot find a way.
Have you any idea how to do it?
I could eventually "convert" my list of array in anything else that could be binded in a datagrid?
The idea is to have a sort of 2d Matrix showed inside the datagrid in Silverlight (I think that the problem is similar).
List
column_1 column_2 column_3 .. column_m
string[1,1] string[1,2] string[1,3] .. string[1,m]
string[2,1] string[2,2] string[2,3] .. string[2,m]
string[3,1] string[3,2] string[3,3] .. string[3,m]
....
string[n,1] string[n,2] string[n,3] .. string[n,m]
n is list lenght, m is list column max number.
Any idea is appreciated
I've found two solution to the problem that use the schema in the Denis's answer:
the first one is to use reflection to generate a class at runtime for the binding as suggested in this article (thanks to Vladimir Bodurov). I've tested this solution and I'll try to use it on my project. The only problem right now is that for large collection, the performance are poor. But I hope that someone will fix it in next relese (Silverlight 3 seems to not have fixed this problem, yet)
the second solution will be using some dynamic language for generate data. I don't know if this could be faster or not (probably not) but eventually could help. I will try in the future and use ironpython or ruby to generate classes that will be binded in datagrid.
If anyone have tryed using the second solution or any performance related information about creating classes at runtime, it will be appreciated.
Giorgio
Unfortunately that's not gonna be easy.
Do you have any valid constraints, like the maximum number of columns that is allowed or anything like that?
If you do (let's say you have N column maximum), you might be able to do something by
Having a class that exposes N
properties (named Col1...ColN for
example) that map the content
of the array for one line at column
X
Generating a list of that class,
one instance for each line
Generating the correct number of
column on the fly, binding each
column to property ColX
Binding your DataGrid to that list
That's kind of ugly, but it would work.
If you do not have to rely on the DataGrid, there is a possibility using a UniformGrid. A UniformGrid is a panel that layouts its children in a regular grid (every item has the same width, every item has the same height). You can indicate the number of columns at runtime, and the panel will fit children one after the other up to the number of columns and then continue on another line.
You could bind an ItemsControl to your array, indicating it should use a UniformGrid as its layout panel and indicating a suitable ItemTemplate to render each string.
The second option is much easier, but you will not have the capabilities of the DataGrid like sorting, moving columns, row selection, edition events per row etc.
Does anyone known (or even has an example) of a WPF based TreeListView that can generate its colums by databinding to the ObservableCollection of its tree items?
For example the databound model is a tree consisting of Employee instances representing the supervisor hierarchy of a company. Each employee addtionally has a ObservableCollection of Responsibility instances (Properties: ResponsibiltyName, ResponsibleSinceDate). Now I want a separate column for each ResponsibiltyName found in any of the databound Employees and the column value should be populated with the ResponsibleSinceDate. If an Employee does not have a certain Responsibilty the column value shall be left blank.
How would one usually approach such a problem in WPF?
You may want to take a look at the following answer: How do I bind a WPF DataGrid to a variable number of columns?
Here a solution involving a CompositeCollection is suggested: http://social.msdn.microsoft.com/forums/en-US/wpf/thread/a4c5b2de-260c-49d0-b4ff-cca6ee4e8b08/
Here a solution involving a HierarchicalDataTemplate is suggested: http://blogs.msdn.com/karstenj/archive/2005/11/02/488420.aspx
Hope this helps!