Я знаю, что это старый вопрос с ответом, но у меня другой подход. Мне нравится делать неявные отношения в файле App.xaml:
<Application.Resources>
<DataTemplate DataType="{x:Type ViewModels:KioskViewModel}">
<Views:KioskView />
</DataTemplate>
</Application.Resources>
При этом нет необходимости устанавливать DataContext в любом месте.
ОБНОВЛЕНИЕ >>>
В ответ на запрос @Vignesh Natraj, вот более полное объяснение:
После того, как вы настроили DataTemplate
в элементе Resources
, вы можете отобразить KioskView
в этом примере, добавив экземпляр KioskViewModel
в любом месте вашего XAML. Это может быть заполнение MainWindow
или только внутри определенного раздела экрана. Вы также можете разместить несколько экземпляров KioskViewModel
в ListBox
, и он будет генерировать несколько экземпляров KioskView
.
Вы можете добавить экземпляр KioskViewModel
в свой XAML несколькими способами, в зависимости от ваших требований. Один из способов - объявить пространство имен XML для проекта, содержащего файл KioskViewModel.cs
, и просто добавить его экземпляр в ContentControl
на страницу, где вы хотите, чтобы ваше представление отображалось. Например, если у вас есть UserControl
с именем MainView
, а файл KioskViewModel.cs
находится в пространстве имен Kiosk.ViewModels
, вы можете использовать базовый XAML, например:
<UserControl x:Class="Kiosk.Views.MainView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ViewModels="clr-namespace:Kiosk.ViewModels">
<UserControl.Resources>
<ViewModels:KioskViewModel x:Key="KioskViewModel" />
<DataTemplate DataType="{x:Type ViewModels:KioskViewModel}">
<Views:KioskView />
</DataTemplate>
</UserControl.Resources>
<ContentControl Content="{StaticResource KioskViewModel}" />
</UserControl>
Я предпочитаю использовать шаблон проектирования MVVM с WPF, поэтому у меня будет класс модели базового вида, обеспечивающий полезные функции, такие как реализация необходимого интерфейса INotifyPropertyChanged
. Затем у меня есть свойство с именем ViewModel
в модели основного (верхнего уровня) вида BaseViewModel
. Это дает мне хороший способ изменить свойство ViewModel
на любую модель представления, основанную на BaseViewModel
, и, следовательно, иметь возможность изменять связанный вид из модели представления.
Например, в классе MainViewModel.cs
, связанном с MainView
, есть поле и соответствующее свойство:
private BaseViewModel viewModel = new KioskViewModel();
public BaseViewModel ViewModel
{
get { return viewModel; }
set { viewModel = value; NotifyPropertyChanged("ViewModel"); }
}
Как видите, он запускается как экземпляр KioskViewModel
, но может быть изменен на любое другое представление в любое время в ответ на взаимодействие с пользователем. Для этой настройки XAML очень похож, но вместо объявления экземпляра модели представления в элементе Resources
мы связываемся со свойством в MainViewModel
:
<UserControl x:Class="Kiosk.Views.MainView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ViewModels="clr-namespace:Kiosk.ViewModels">
<ContentControl Content="{Binding ViewModel}" />
</UserControl>
Обратите внимание, что для этого примера нам нужно объявить два (или больше, чтобы сделать этот подход полезным) DataTemplate
s в файле App.xaml
:
<Application.Resources>
<DataTemplate DataType="{x:Type ViewModels:MainViewModel}">
<Views:MainView />
</DataTemplate>
<DataTemplate DataType="{x:Type ViewModels:KioskViewModel}">
<Views:KioskView />
</DataTemplate>
</Application.Resources>