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
According to the MV(V)C Pattern there should not by any "functionality" in any View.
The functionality should be in the controller layer which handles the applications state by altering the model as needed.
Now you can have as many view layers (in parallel or sequentially) viewing the model data and manipulating them via the controller.
Since the model provides infrastructure to propagate changes the View B can register for certain Properties to get change information so that it can update itself when View A changed that property.
Do not put your fath on that names. After all names are just dust in the wind.
The point is that you have to deal with this 3 layers model, controller, and view. The different names (MVC,MVVC, MCP) are only variation and don't mean that much to me.
You also do not necessarily put them into separate projects, packages or classes. The pattern is basically about the direction of communication:
*Listener
interfaces).