I need help creating view models for the following scenario:

  1. Deep, hierarchical data
  2. Multiple views for the same set of data
  3. Each view is a single, dynamically-changing view, based on the active selection
  4. Depending on the value of a property, display different types of tabs in a tab control

enter image description here

My questions:

Should I create a view-model representation for each view (VM1, VM2, etc)?

1. Yes:
    a. Should I model the entire hierarchical relationship? (ie, SubVM1, HouseVM1, RoomVM1)
    b. How do I keep all hierarchies in sync? (e.g, adding/removing nodes)

2. No:
    a. Do I use a huge, single view model that caters for all views?

Here's an example of a single view

Figure 1: Multiple views updated based on active room. Notice Tab control

enter image description here

Figure 2: Different active room. Multiple views updated. Tab control items changed based on object's property.

enter image description here

Figure 3: Different selection type. Entire view changes

enter image description here

  • btw what is a muli view? typo? – JensG Mar 17 '14 at 15:52
  • "Muli view" was a typo. I meant different views for the same model/view model. My question was, should I remodel/wrap the entire model hierarchy for each view, so each view model only contains what the individual view needs? Or should I create a single view model hierarchy that contains properties from all views? Since I posted this question, I was (un)fortunate enough to find out the pros/cons of the two, the hard way. Will update this thread in the future with a full diagnosis of my experience, once things aren't as hectic. – jayars Mar 18 '14 at 10:20
  • Remember a design rule is to show general things first then go deep into details. it will leave you with a light view and if the user go deeper then new views will appear. so use small views with their viewmodel apart. check this article design user interface – Csharls Jul 23 '14 at 23:29
  • @jsjslim I shuddered when I read "keep all hierarchies in sync". I suspect you went with the multi-view, and I suspect you regretted it (but I've been wrong before). For the sake of other readers who may have the same question, can you at least give us a quick(ish) answer? – Guy Schalnat Jul 24 '14 at 2:15
  • 2
    @guy-schalnat The multi-view was a requirement. My problem was trying to figure out how to build the view models. The project is still ongoing, and I can't find the time to write-up a full analysis. But in summary: I should have ignored the model structure, and focused on the views. The complexity that I encountered was self-imposed: I wanted to use WPF's data binding so badly, I got fixated. What I did in the end was good, old "copy/paste/refactor". The final design that emerged was lightweight (little repetition), and more importantly, worked. Will write up a full analysis in the future. – jayars Jul 25 '14 at 0:59

To answer the question, Yes, each view should have its own View Model. But there is no need to model the entire hierarchy. Only what the view needs.

The problem I had with most online resources regarding MVVM:

In most examples, the View is almost 1-to-1 mapping of the Model. But in my scenario, where there are different views for different facets of the same Model, I find myself stuck between two choices:

One monolithic view model that is used by all other view models

enter image description here

Or one view model for each view

enter image description here

But both are not ideal.

The Model-oriented View Model (MVM), while low in code duplication, is a nightmare to maintain

The View-oriented View Model (VVM) produces highly-specialised classes for each view, but contains duplicates.

In the end, I decided that having one VM per View is easier to maintain and code for, so I went with the VVM approach.

Once the code is working, I began refactoring all common properties and operations into its current, final form:

enter image description here

In this final form, the common view model class is composed into each VVM.

Of course, I still have to decide what is considered common/specialised. And when a view is added/merged/deleted, this balance changes.

But the nice thing about this is, I am now able to push up/down members from common to VVM and vice versa easily.

And a quick note regarding keeping the objects in-sync:

Having a Common View Model takes care of most of this. Each VVM can simply have a reference to the same Common View Model.

I also tend to start with simple callback methods, and evolving to event/observer if the need for multiple listeners arise.

And for really complex events (ie, unexpected cascading updates), I would switch over to using a Mediator.

I do not shy away from code where a child has a back reference to its parent. Anything to get the code working.

And if the opportunity to refactor arise, I would take it.

The lessons I learnt:

  1. Ugly/Working code > Beautiful/Non-working code
  2. It is easier to merge multiple small classes, than it is to break up a huge class
  • I wish I could upvote this twice. This is one of the clearest explanations of the options I've seen. – CleverPatrick Jan 22 '18 at 14:32

Looking at your mockups, I would definitely recommend creating hierarchy of ViewModels and lots of small Views. And you will most probably have to model quite a bit of the original hierarchy.

To keep things in sync between ViewModels, use either events, or have properties to each other between ViewModels. Sync between Views and ViewModels should be standard notifying properties.

Not the answer you're looking for? Browse other questions tagged or ask your own question.