3

I have a MVVM/WPF based application that can have multiple workspaces (basically containing a TreeView) open at the same time that display and operate on the same data tree. I need to be able to expand and collapse and select the items in each workspace independently and I want to be able to drag and drop items between the two workspaces (e.g. for moving or duplicating items). I also need data virtualization in that the data is only loaded (in both views) when a tree item is expanded for the first time. There is also one workspace-wide details view that shows the details of the selected item of the workspace that currently has the focus. Workspace specific expansion and selection of items must also work programatically.

Could you layout a ruff design for a MVVM based application that embraces theses features? Should I create a separate ViewModel tree for each workspace and implement a Model-ViewModel mapper? Or should I have just one ViewModel tree with two Views? How does the details view know what is currently selected and what workspace has the focus? ...

So to rephrase my question: The Model instances displayed in each View are actually the same instances. But should the ViewModels be the same too? Or better: Could I possibly get away with that?

Also: Is there an open source application I could study that has most of these features? Could Prism or any other MVVM based framework do most of that work for me?

2 Answers 2

2

There is a direct correlation between View and ViewModel. The View shows a visual representation of the Model, hosted and "formatted" by the ViewModel.

Since you will have different Model (data) on each View, you need to have several instances of your ViewModel hosting each set of different data.

Now the question is: do your ViewModels share some entities or objects between them ? If yes, could they change during your application lifetime, and do you want to see these changes in realtime in your TreeViews ?

You then have two options:

  1. Directly bind the model to the View (if the model implements INotifyPropertyChanged) by exposing it through your ViewModel: then all your views will be automatically updated when a model property changes.
  2. Create a component which supervises Model modifications and notify ViewModel exposing them.

The second solution is more pure than the first one because Models should be POCO and shouldn't implement some plumbing oriented-interface. ViewModel should handle the plumbing.

However it's more complicated to design, and 90% of the time, you will end-up saying "come on, just one little interface doesn't hurt" :)

For your details view. You can communicate between your TreeViewModel and your DetailViewModel using a mediator (Messenger in the MVVM Light Toolkit), which is basically a low-coupled event-oriented component. Or use a supervisor which is injected in all your ViewModel and notify them using events.

Speaking of MVVM framework, and for common architecture like the one you are describing, I would recommend the MVVM Light Toolkit.

Sign up to request clarification or add additional context in comments.

6 Comments

So you say I should go the multiple ViewModel route? Just to make sure: I don't have different Model (data) on each View. I have multiple Views one same data (Model). The Model instances displayed in each View are actually the same instances. But should the ViewModels be the same too? Or better: could I possibly get away with that?
If I understood you well, you want to enable Drag and Drop between different TreeViews. So your collection of item encapsulated in your ViewModel are likely to change. Some will lost items and others will gain some. Then you cannot have one ViewModel for all Views, since the collections for each ViewModel are not equals. I assume there can be some exceptions where you can get rid of the ViewModel for really simple scenario. But it implies that you have put plumbing in your Model. But once again, it should be the job of the ViewModel. Anyway, it doesn't seem to fit your scenario.
Wait: If I drag from one VM-tree to another VM-tree that is based on the same Model the drag and drop will still result in both VM-trees having exactly the same data. So both trees will always have exactly the same data structure, wouldn't they? It is just their expansion and selection states that are different. Dragging and dropping between the two ViewModel-trees is nothing else that moving or duplicating items within the same Model-tree.
I must say I don't quite follow you. When you will be dragging an item from TreeView 1 to TreeView 2, the item will be removed from the collection bound to TreeView 1 and added to the TreeView 2. The bound data is not the same, so they can't be linked to the same ViewModel (or Model with plumbing :)
When I drag items from one tree to the other nothing changes in both trees. Only when I drop the items, the changes will applied. But the changes will occur in both trees identically because they represent the same Model-tree. Dropping the item will modify the one and only Model-tree immediatly. After the drag&drop both trees will still look exactly the same because it is they represent the very same Model-tree. What I just did with my drag&drop operation was to move an item from one position to another position within the same Model-tree.
|
0

Maybe I am missing something, but is it not possible to have 2 instances of the same View / ViewModel loaded with different data?

1 Comment

Yes this is possible. I have one Model (the data tree) but need two rather independent views on it. Should I have two ViewModel trees (one for each view) that both point to the same model? Or can I get away with one ViewModel tree that is bound to in 2 Views? My question is geared to an overal "best practise" for the rather common requirements above.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.