views:

69

answers:

3

So when i have a Datagrid which i want to fill with data from my Database. I normally design a ViewModel with the Data i wanted to display. But how do i create an ViewModel for my Datagrid when i dont know before which data it will display in it ?

So when i allow the user of my application to specify the Columns from the database table which he wants to display in the Datagrid. How do i design the ViewModel for that case ?

So i hope its clear what i want to do.

thx in advance

+2  A: 

Two solutions spring to mind.

  1. Have the ViewModel hold all the columns and just have the user selected ones on the View. This is not ideal.

  2. Use reflection on the View data to determine the columns for the ViewModel.

ChrisF
the first solution i think so too is not that what im looking for. I will read some msdn published articles about reflection and than update my question when i need further advice. thx for the hint!
Mark
+2  A: 

I have done this before in the following way:

  • an XML document is used which describes all the available columns, their formatting (i.e. "#0.#0" for numeric columns), and the data field they bind to, it also describes which columns are the default ones

  • this column description XML is retrieved via a WCF call to the server (this was a Silverlight project)

  • the grid columns are generated by the View using a grid column factory (this is done by the View because it is heavily UI dependant). The default columns are set to visible, the others are set to not visible

  • the ViewModel is populated with a list of data objects containing all the data for the columns

  • the user can right click on the grid and via the context menu bring up a dialog containing the complete list of columns, with a tick (check) mark next to the ones that are currently visible. This dialog is managed/populated from the View - as the ViewModel should not know anything about the actual UI. You may want to use a dialog service for this. The dialog's VM is populated with a list of anonymous objects containing the column captions and the visibility state of the column.

  • upon the user closing the dialog the View will show/hide the appropriate columns (i went a step further - as the user checks a column in the dialog it instantly becomes visible in the grid so that the user knows they chose the right one, when displaying many tens of columns quite a few could be very similar).

The advantage of using the XML document to describe the columns is:

  • it is UI agnostic; it doesn't matter what grid component i use all i have to do is change the factory

  • the XML document can be updated separately to the code; if a client wants a format string changed i don't have to recompile the code. Similarly if i need to show more data in the future all i need to change is my XML document, the assembly containing the data object definitions, and the DAL assembly - the V/VM don't need to be changed at all.

slugster
that sounds really nice which options you provide for the user. I will fetch some of them ;) thx
Mark
A: 

Do you even need to create a view model? Can't you just populate a local DataTable and bind the DataGrid to it? There's an enormous amount of functionality baked in to the ADO objects, and the DataGrid interoperates with a lot of it. If you really need additional properties on the DataRow (like commands, say), you can subclass DataTable and DataRow and add them. This could save you a lot of work.

Whether you create a DataTable or create your own class, a fairly simple approach is to set AutoGenerateColumns to true and handle the DataGrid.AutoGeneratingColumn event. You can hook in a list of columns that you want to hide, and then set e.Cancel to true when the column being generated is in that list. The documentation shows an example of what this looks like.

Robert Rossney