My application has user controls within user controls. Please see a screen shot of one of the most beautiful applications of all time (UC = user control):
All the properties live in the MainWindow code behind, there are none in my UserControls. To bind to my properties I use
DataContext="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorLevel=1,AncestorType=Window}}"
This works fine but, it does mean all binding properties are in my MainWindow code behind (or the MainWindow ViewModel).
Is this desired in a MVVM (or should I say WPF) approach, in that all the children share the same ViewModel?
Best Answer
I think its bad practice to have a God ViewModel, the topmost ViewModel, let's call it
MainWindowViewModel
, should only hold data and behavior coupled to that of the MainWindow, which usually is very thin, all other work should be delegated to submodels.If you have a docking manager or other window manager logic that code should reside in the
MainWindowViewModel
.Here is a example of a ViewModel I've made that delegates the behavior to sub models
https://github.com/AndersMalmgren/FreePIE/blob/master/FreePIE.GUI/Shells/MainShellViewModel.cs
I do not think it's good practice to pass around data to sub models, it creates dependencies between models. It's better to use a Event aggregation pattern, this way all models interested in data change can subscribe to the event.
Update: I did an improvement to my Main window model, instead of the constructor taking all sub view models it now takes a collection of viewmodels. And then I configure the IoC to inject correct models
This makes the main model a little less coupled to the sub models, before change
and after
https://github.com/AndersMalmgren/FreePIE/commit/1102292d35a26d7693593266042cde9d9f3b4c89