Ответ 1
Вы бы сделали это в своей родительской ViewModel.
Например, если ваша страница (назовите ее PageViewModel
) имеет два вида (ViewModelA
и ViewModelB
), у вас будет свойство на PageViewModel
, называемое CurrentView
, и это определит, какой вид видимый. Если для PageViewModel.CurrentView
установлен экземпляр ViewModelA
, то для рисования содержимого используется ViewA DataTemplate. Когда он установлен в экземпляр ViewModelB
, отображается ViewB DataTemplate.
<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>
Было бы идеально назвать команду представлений switch из родительского представления (в этом случае DataTemplate для PageViewModel
), однако, если вы хотите переключать представления из ViewModelA/B, вы можете либо подключить событие вручную, когда объекты создаются (CurrentView.ChangeViewCommand = this.ChangeViewCommand
) или заглядывают в систему обмена сообщениями. MVVM Light имеет простой класс Messenger
, который я нашел, был довольно прост в использовании, или Prism имеет более продвинутый EventAggregator
Если вы хотите переключать Views для одного и того же ViewModel, я бы рекомендовал свойство Mode, которое используется для определения того, какой вид использовать. Например:
<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>
ИЗМЕНИТЬ
Я действительно вижу, что этот вопрос возникает много, поэтому разместил что-то об этом здесь, если кому-то интересно