Composable Views in a treeview ?

Jan 12, 2011 at 9:40 PM

I'm just beginning a new WPF project in which we're hoping to use Caliburn.Micro.

At this stage I'm just a little confused about how Views and ViewModels can be divided up and composed.

Our interface is going to be one big treeview (plus a details panel, but ignore this for the time being) with which you navigate and operate on all the different business objects we have - basically, something like Windows Explorer. At first I was imagining that we would end up with one View, because I mentally equate a view with a physical screen.

However, in terms of dividing up work and responsibility, I can see that it could make sense to have lots of different ViewModels, one for each kind of object that will be in the treeview. This way, each ViewModel can concentrate on its own business object, without having to worry too much about others. For example, consider a tree structure that contains Customers, Customers contain Orders, and Orders contain Items. We could have separate ViewModels for Customer, Order and Item.

Given that ViewModels are just normal classes, we can then compose these ViewModels - eg, the Person ViewModel can have a list of Order ViewModels, etc.

But, it gets confusing to think about how this relates to the Views. Each ViewModel should have a corresponding View ? Given everything is ending up on the one screen in the same treeview, is it possible to make 3 separate XAML Views, and somehow compose these ? Or should we just have one View, which somehow makes use of the 3 ViewModels ?

If in contrast to a treeview, for example, when you clicked on a person, a separate window opened to show all the orders for that person, it's much easier to envisage that as a separate view.

Hope this makes sense - let me know if it doesn't, so I can clarify if necessary.

So basically, in general, what is the usual way of thinking about the structure of ViewModels and Views in this kind of situation ? ie, displaying lots of different kinds of things on the one screen.

Any advice is greatly appreciated ! Are there any good examples out there I could look at ?

Thanks :)

Coordinator
Jan 12, 2011 at 9:46 PM

Are you saying that the entire UI is a TreeView only. Or is it that when things are selected in the TreeView a different part of the UI updates with the detail view?

Jan 12, 2011 at 9:54 PM

The UI will be potentially be something like Windows Explorer with the treeview navigation pane on one side, and a details view on the other.

So, when you select an object in the treeview, the details pane will show details about the selected object.

For example, if you selected a Person, you'd see things like Name, Address etc in the details pane. In the treeview, you could expand the Person to show the Orders for that Person.

Coordinator
Jan 12, 2011 at 10:07 PM
Edited Jan 12, 2011 at 10:08 PM

Ok. I thought something like that. Read through this http://www.codeproject.com/KB/WPF/TreeViewWithViewModel.aspx

If you use his TreeViewItemViewModel in combination with the styles he suggests, then anytime the IsSelected property changes to true, you could fire off an event with the EventAggregator which would be picked up by another VM. This other VM would be a Conductor<T> and would change it's ActiveItem based on the data in the event. The ActiveItem would be bound to your detail pain and would pick up the appropriate view based on convention.

Let me know if that helps. It's not the only way to do it, but it should work pretty well and keep things nicely decoupled.

Jan 12, 2011 at 11:47 PM

Thanks very much for that - that article is really helpful.

So, if what I understand is correct :-

- Yes, I can have a ViewModel for each kind of object, and those ViewModels get composed, eg a parent ViewModel contains a list of child ViewModels, such as StateViewModel containing its children CityViewModels

- For my detail screens, there'll be a View for each of the above ViewModels

- For the treeview, there's an additional ViewModel, and a corresponding View

This does seem nicely structured - I'll have a go at implementing it :)

Thanks again for your help :)

Coordinator
Jan 13, 2011 at 12:09 AM

Don't feel compelled to create different view models for the nodes in your tree view, unless you have a good reason for that. You may be able to use a simple generic tree structure such as Josh demonstrates. I just don't want you to feel like you need to have all that unless you need it. The main place you will probably need a ViewModel is for the detail view.

Jan 18, 2011 at 5:19 AM

Hi,

I've managed to implement something similar to what you suggested (but I haven't yet got my head around Screens and Conductors).

For now, I've just got a main view which has my Treeview, and a ContentControl. The ContentControl is bound to the currently SelectedItem (via the Name convention).
When an item is selected in the Treeview, it uses the EventAggregator to let the main view know which item was selected, and to set SelectedItem to that item.
I've got a View for each different kind of item in the tree, and Caliburn very nicely displays the appropriate view for the selected item.

So, it all works quite well !

(I'll read up more on the Screens and Conductors too :)

Thanks again ! :)