I started off binding ContentControls
to Views stored in my ViewModels
, and while it worked as intended, it broke the MVVM
pattern I've been trying to follow. It just felt dirty. So, based on the recommendation of someone in chat, I learned about DataTemplates
, implemented it, and it has been an awesome solution. However, I have run into a snag, most likely the limits of my knowledge, so here I am and thanks in advance.
The description of my problem is based on what I've gathered about using DataTemplates
, so if my premise is wrong, it would be wonderful if you'd hit me up in the comments so I can better my understanding (and for others too if they find this question).
A ContentControl
's Content attribute binds to a property in ViewModel
with a type referring to some interface implemented by any ViewModel
that may be desired. Whenever the property is set to the appropriate ViewModel
, the ContentControl
looks at the DataTemplate
to determine which View
to load and then it initializes the corresponding View and then that View
initializes it's own ViewModel
. This last sentence is pretty pivotal so if I'm wrong about that, my understanding is off and the nature of my problem is not what I think it is. Here is a code snippet from a UserControl
containing a DataTemplate
:
<UserControl.DataContext>
<viewModels:ControlCenterVM />
</UserControl.DataContext>
<UserControl.Resources>
<DataTemplate DataType="{x:Type moduleViewModels:StateVM}">
<moduleViews:StateView/>
</DataTemplate>
<DataTemplate DataType="{x:Type moduleViewModels:InputVM}">
<moduleViews:InputView/>
</DataTemplate>
<DataTemplate DataType="{x:Type moduleViewModels:TemperatureVM}">
<moduleViews:TemperatureView/>
</DataTemplate>
<DataTemplate DataType="{x:Type moduleViewModels:NetworkControlVM}">
<moduleViews:NetworkControlView />
</DataTemplate>
</UserControl.Resources>
<ContentControl Content="{Binding LeftModule}" />
The View
that is loaded creates a new ViewModel
. The ViewModel
I should be using is actually the same exact one that I set to the property bound to the ContentControl
but it seems to me that it only uses it to do type-matching for the View
lookup. Is this correct?
Look at the DataContext
portion of the code snippet I provided above. All of my Views
, especially the ones that "could" be loaded into the ContentControl
, create their DataContext
like this. How can I refer to a static ViewModel
in those areas?
Thanks again.
Whenever the property is set to the appropriate ViewModel, the ContentControl looks at the DataTemplate to determine which View to load and then it initializes the corresponding View and then that View initializes it's own ViewModel.
You were right about everything except that last part which I've highlighted.
Setting the Content
property for the ContentControl
effectively sets the DataContext
for the view it displays. This means that you don't have to set the ViewModel
explicitly from your views.
Simply remove any modifications you've made to the DataContext
property in your views and everything should be working as expected.