Navigation should always be handled in the ViewModel.
You're on the right track with thinking that the perfect implementation of the MVVM design pattern would mean you could run your application entirely without Views, and you can't do that if your Views control your Navigation.
I usually have an ApplicationViewModel
, or ShellViewModel
, which handles the overall state of my application. This includes the CurrentPage
(which is a ViewModel) and the code for handling ChangePageEvents
. (It's often also used for other application-wide objects such as the CurrentUser, or ErrorMessages too)
So if any ViewModel, anywhere, broadcasts a ChangePageEvent(new SomePageViewModel)
, the ShellViewModel
will pickup that message and switch the CurrentPage
to whatever page was specified in the message.
I actually wrote a blog post about Navigation with MVVM if you're interested
So I think you have some minor violation of MVVM | MVPVM patterns due to linkage you're creating between the views. Neither pattern is all that verbose with respect to child windows though, so it's a bit of a murky area.
I think it's worth pointing out that the big advantage of MVPVM vs. MVVM is because of separating out business logic. The VM becomes a data container and the P handles logic plus DAL access. Bill Kratochvil's article on MVPVM was a very good read.
Bill makes a comment regarding child windows and re-use that I think is apt:
In cases where a Presenter can be reused across enterprise applications, it’s likely a module would be better suited for the task—that is, you could create a login module (project) that could be reused by all of your enterprise applications.
Which kind of reinforces that you're in murky territory with two child components.
Regardless of MVVM or MVPVM, I think you would need either
B-VM
and C-VM
when using MVVM
B-P
and C-P
and B-VM
and C-VM
when using MVPVM
because they are functionally separate from A. If they're not functionally separate, then why do they need their own Views?
I think the challenges you bring up with swapping ViewB and ViewC is because there is some blurring between object ownership and responsibilities. Which is really just another way of asking if B and C are functionally separate from A or not. If they are, then make them that way and if not, then don't set them up as independent.
For lightweight stuff without a lot of business logic that could be re-used, I think that MVPVM is more effort than it's worth with MVVM. That's clearly a generality, and the business logic of your application may lend itself to being expressed more elegantly with MVPVM. Based upon your question though, it sounds like MVVM may be sufficient for what you need.
Best Answer
This is how I see (and do) it.
In your case (which is rather simple), I would have a ViewModel holding a list of Models and a SelectedModel property. The view would have a form and a list of course. The form would be bound to the currently selected model. The View would be bound to the ViewModel and indirectly to the Model (the data in the list and the form). Your ViewModel would also take care of validating and saving the data to the database by calling a method on your repository (or the Context, which is basically a repository, if you're using EF).
The Model is your business logic, the Domain Model. The objects here will have all the data relevant to the business and the methods to manipulate that data. The model should be designed to be as simple as possible while accomplishing the business needs. This means normalized relationships, decoupled design and so on. Make it as easy to maintain as possible, regardless of the view. This means the same Model can be reused in different applications (a desktop and a web app can use the same model). In your case this is an object with the Name, Address and Description. This is all you need to accomplish your goal.
The View will not always be this simple. Sometimes you will need to aggregate data from multiple models, or do some other manipulation of the data just to show the data on a view. A report for instance, can have lots of data from lots of models. Other times, the view will really need to simplify a lot of complex things that are going on in the model, to give you a high level overview without too many details. In your case, the view is also a bit more complex than your domain model. You need a list to see all your domain models and a form to edit one at the same time.
This is where the ViewModel comes in. The VM will be between the model and the view. It will wrap a model object (or multiple model objects), introduce new properties that are a combination of other properties in the model and so on. The ViewModel is the one that is designed in a way that it makes presentation easier. This means simple properties your view can bind to and similar things. No matter how complex your Model or your View is, your ViewModel sits in between and makes all the necessary transformations of the data that you want to display. The same thing but in reverse happens when a view is sending data back (form submission or other input). The ViewModel is the one that transforms the view data into something that your Model understands. In your case the ViewModel will be rather simple, holding just the list of Models and a Selected Model, but in more complex examples, it might do some calculations or whatnot to accomplish what the view needs.