Язык программирования C#9 и платформа .NET5
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();}Добавьте в начало файла следующий оператор
:usingusing WpfViewModel.ViewModels;Создайте строго типизированное свойство для хранения экземпляра модели представления:
public MainWindowViewModel ViewModel { get; set; }= new MainWindowViewModel();Добавьте свойство
к объявлению окна в разметке XAML:DataContextDataContext="{Binding ViewModel, RelativeSource={RelativeSource Self}}"Обновление разметки элементов управления
Теперь, когда свойство
дляDataContextустановлено в модель представления, потребуется обновить привязки элементов управления в разметке XAML. Начиная с поля со списком, модифицируйте разметку за счет добавления свойстваWindow:ItemsSource<ComboBox Name="cboCars" Grid.Column="1" DisplayMemberPath="PetName"ItemsSource="{Binding Cars}" />Прием работает, т.к. контекстом данных для
являетсяWindow, aMainWindowViewModel— открытое свойство модели представления. Вспомните, что конструкции привязки обходят дерево элементов до тех пор, пока не найдут контекст данных. Далее понадобится обновить привязки для элементов управленияCars. Задача проста; поскольку привязки уже установлены на уровне окна, нужно лишь модифицировать конструкции привязки, чтобы они начинались со свойстваButton:DataContext<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
Если вы хотите обновить проект
для MWM, то должны применить изменения, которые вносились вAutoLot.Dal, ко всем сущностям в проектеCar, включаяAutoLot.Dal.Models.BaseEntity