I\'m relatively new to WPF and MVVM and the hardest thing I have found is how to simply switch a usercontrol or a view in an application.
In winforms, to have a cont
You would do so in your parent ViewModel.
For example, if your page (call it PageViewModel
) had two views (ViewModelA
and ViewModelB
), you would have a property on PageViewModel
called CurrentView
, and this would determine which View is visible. When PageViewModel.CurrentView
is set to an instance of ViewModelA
, then ViewA's DataTemplate is used to draw the content. When it's set to an instance of ViewModelB
, ViewB's DataTemplate is displayed.
<DataTemplate DataType="{x:Type local:PageViewModel}">
<ContentControl Content="{Binding CurrentView}" />
</DataTemplate>
<DataTemplate DataType="{x:Type local:ViewModelA}">
<TextBlock Text="I'm ViewModelA" />
</DataTemplate>
<DataTemplate DataType="{x:Type local:ViewModelB}">
<TextBlock Text="I'm ViewModelB" />
</DataTemplate>
It would be ideal to call the switch views command from the parent view (in this case the DataTemplate for the PageViewModel
), however if you wanted to switch views from within ViewModelA/B, you can either hook up the event manually when the objects get created (CurrentView.ChangeViewCommand = this.ChangeViewCommand
) or look into a messaging system. MVVM Light has a simple Messenger
class which I found was fairly easy to use, or Prism has a more advanced EventAggregator
If you want to switch Views for the same ViewModel, I would recommend a Mode property that gets used to determine which view to use. For example:
<DataTemplate x:Key="ViewA" DataType="{x:Type local:MyViewModel}">
<TextBlock Text="I'm ViewModelA" />
</DataTemplate>
<DataTemplate x:Key="ViewB" DataType="{x:Type local:MyViewModel}">
<TextBlock Text="I'm ViewModelB" />
</DataTemplate>
<DataTemplate DataType="{x:Type local:MyViewModel}">
<ContentControl Content="{Binding }">
<ContentControl.Style>
<Style TargetType="{x:Type ContentControl}">
<Setter Property="ContentTemplate" Value="{StaticResource ViewA}" />
<Style.Triggers>
<DataTrigger Binding="{Binding Mode}" Value="2">
<Setter Property="ContentTemplate" Value="{StaticResource ViewB}" />
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
</DataTemplate>
EDIT
I actually see this kind of question come up a lot, so posted something about it here if anyone is interested