new Car { Id = 1, Color = "Blue", Make = "Chevy",
PetName = "Kit", IsChanged = false });
Cars.Add(
new Car { Id = 2, Color = "Red", Make = "Ford",
PetName = "Red Rider", IsChanged = false });
}
Далее переместите весь код, относящийся к командам, из файла отделенного кода окна в модель представления, заменив ссылку на переменную _cars ссылкой на Cars. Вот измененный код:
// Для краткости остальной код не показан
private void DeleteCar(Car car)
{
Cars.Remove(car);
}
Обновление кода и разметки MainWindow
Из файла MainWindow.xaml.cs кода была удалена большая часть кода. Удалите строку, которая устанавливает ItemsSource для поля со списком, оставив только вызов InitializeComponent(). Код должен выглядеть примерно так:
public MainWindow()
{
InitializeComponent();
}
Добавьте в начало файла следующий оператор using:
using WpfViewModel.ViewModels;
Создайте строго типизированное свойство для хранения экземпляра модели представления:
public MainWindowViewModel ViewModel { get; set; }
= new MainWindowViewModel();
Добавьте свойство DataContext к объявлению окна в разметке XAML:
DataContext="{Binding ViewModel, RelativeSource={RelativeSource Self}}"
Обновление разметки элементов управления
Теперь, когда свойство DataContext для Window установлено в модель представления, потребуется обновить привязки элементов управления в разметке XAML. Начиная с поля со списком, модифицируйте разметку за счет добавления свойства ItemsSource:
<ComboBox Name="cboCars" Grid.Column="1" DisplayMemberPath="PetName"
ItemsSource="{Binding Cars}" />
Прием работает, т.к. контекстом данных для Window является MainWindowViewModel, a Cars — открытое свойство модели представления. Вспомните, что конструкции привязки обходят дерево элементов до тех пор, пока не найдут контекст данных. Далее понадобится обновить привязки для элементов управления Button. Задача проста; поскольку привязки уже установлены на уровне окна, нужно лишь модифицировать конструкции привязки, чтобы они начинались со свойства DataContext:
(window.adrunTag = window.adrunTag || []).push({v: 1, el: 'adrun-4-390', c: 4, b: 390})
<Button x:Name="btnAddCar" Content="Add Car"
Margin="5,0,5,0" Padding="4, 2"
Command="{Binding Path=<b>DataContext.AddCarCmd</b>,
RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType={x:Type Window}}}"
CommandParameter="{Binding ElementName=cboCars, Path=ItemsSource}"/>
<Button x:Name="btnDeleteCar" Content="Delete Car"
Margin="5,0,5,0" Padding="4, 2"
Command="{Binding Path=<b>DataContext.DeleteCarCmd</b>,
RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType={x:Type Window}}}"
CommandParameter="{Binding ElementName=cboCars, Path=SelectedItem}" />
<Button x:Name="btnChangeColor" Content="Change Color"
Margin="5,0,5,0" Padding="4, 2"
Command="{Binding Path=<b>DataContext.ChangeColorCmd</b>,
RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType={x:Type Window}}}"
CommandParameter="{Binding ElementName=cboCars, Path=SelectedItem}"/>
Итоговые сведения о моделях представлений
Верите или нет, но вы только что закончили построение первого WPF-приложения MWM. Вы можете подумать: "Это не реалистичное приложение. Как насчет данных? Данные в примере жестко закодированы". И вы будете совершенно правы. Это не реальное приложение, а лишь демонстрация. Однако в ней легко оценить всю прелесть паттерна MWM. Представлению ничего не известно о том, откуда поступают данные; оно просто привязывается к свойству модели представления. Реализации модели представления можно менять, скажем, использовать версию с жестко закодированными данными во время тестирования и версию, обращающуюся к базе данных, в производственной среде.
Можно было бы обсудить еще немало вопросов, в том числе разнообразные инфраструктуры с открытым кодом, паттерн "Локатор модели представления" (View Model Locator) и множество разных мнений на предмет того, как лучше реализовывать паттерн MWM. В том и заключается достоинство паттернов проектирования программного обеспечения — обычно существует много правильных способов их реализации, и вам необходимо лишь отыскать стиль, который наилучшим образом подходит к имеющимся требованиям.
Обновление проекта AutoLot.Dal для MWM
Если вы хотите обновить проект AutoLot.Dal для MWM, то должны применить изменения, которые вносились в Car, ко всем сущностям в проекте AutoLot.Dal.Models, включая BaseEntity.