То, что вы хотите сделать, называется отображением местоположения - это достигается без обращения к представлению из виртуальной машины.
Кратчайшим способом было бы иметь свойство наподобие BaseViewModel CurrentViewModel {get;set;}
(сеттер должен вызывать свойство измененное событие) в viewModel позади вашего главного окна.
Эта логика только для ViewModel c должна выбирать другие модели представления для отображения, помещая их в CurrentViewModel. Вы также можете заменить это навигационной службой вашей фреймворк
(Если вы ее не используете, вам не хватает времени)
Затем вы можете настроить управление контентом следующим образом:
<ContentControl Content="{Binding CurrentViewModel}">
<ContentControl.Resources>
<DataTemplate DataType="{x:Type viewModels:FirstViewModel}">
<views:FirstView ViewModel={Binding}/>
<!-- <views:FirstView DataContext={Binding}/> -->
<!-- The first method is preferable -->
</DataTemplate>
<DataTemplate DataType="{x:Type viewModels:SecondViewModel}">
<views:SecondView ViewModel={Binding}/>
</DataTemplate>
<DataTemplate DataType="{x:Type viewModels:AnotherViewModel}">
<views:AnotherView ViewModel={Binding}/>
</DataTemplate>
<ContentControl.Resources>
</ContentControl>
Я надеюсь, что вы можете увидеть шаблон здесь - элемент управления выберет правильный шаблон на основе указанного типа c, который вы указали в CurrentViewModel
. Вы также можете поместить эти шаблоны в app.xaml в App.Resources
, и тогда все ContentTemplates и ItemTemplates будут использовать их автоматически. В этом случае вы можете при необходимости перезаписать их локально в ресурсах каждого элемента управления.
Конечно, это означает, что вы должны добавить все доступные представления в качестве шаблонов.
Поскольку это очень утомительно, у нас есть рамки. Я использовал только ReactiveUI , который способен автоматически находить все представления, но я уверен, что другие платформы также поддерживают эту концепцию.