AncestorType={x:Type Window}}}"
CommandParameter="{Binding ElementName=cboCars, Path=SelectedItem}"/>
Теперь, запустив приложение, вы можете удостовериться в том, что кнопка Delete Car доступна, только если в раскрывающемся списке выбран автомобиль, и щелчок на ней приводит к удалению записи об автомобиле.
Итоговые сведения о командах
На этом краткий экскурс в команды WPF завершен. За счет перемещения кода обработки событий из файла отделенного кода в индивидуальные классы команд появляются преимущества инкапсуляции, многократного использования и улучшенной возможности сопровождения. Если настолько большое разделение обязанностей не требуется, тогда можно применять легковесную реализацию RelayCommand
. Цель заключается в том, чтобы улучшить возможность сопровождения и качество кода, так что выбирайте подход, который лучше подходит для вашей ситуации.
Перенос кода и данных в модель представления
Как и в разделе "Проверка достоверности WPF", вы можете продолжить работу с тем же самым проектом или создать новый и скопировать в него весь код. Вы создадите новый проект по имени WpfViewModel
. В случае работы с проектом из предыдущего раздела обращайте внимание на пространства имен в примерах кода и корректируйте их по мере необходимости.
Создайте в проекте новую папку под названием ViewModels
и поместите в нее новый файл класса MainWindowViewModel.cs
. Добавьте операторы using
для следующих пространств имен и сделайте класс открытым:
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows.Input;
using WpfViewModel.Cmds;
using WpfViewModel.Models;
На заметку! Популярное соглашение предусматривает именование моделей представлений в соответствие с окном, которое их поддерживает. Обычно имеет смысл следовать такому соглашению, поэтому оно соблюдается в настоящей главе. Тем не менее, как и любой паттерн или соглашение, это не норма, и на данный счет вы найдете широкий спектр мнений.
Перенос кода MainWindow.xaml.cs
В модель представления будет перемещен почти весь код из файла отделенного кода. В конце останется только несколько строк, включая вызов метода InitializeComponent()
и код установки контекста данных для окна в модель представления.
Создайте открытое свойство типа IList
по имени Cars
:
public IList
new ObservableCollection
Создайте стандартный конструктор и перенесите в него весь код создания объектов Car
из файла MainWindow.xaml.cs
, обновив имя списковой переменной. Можете также удалить переменную _cars
из MainWindow.xaml.cs
. Ниже показан конструктор модели представления:
public MainWindowViewModel()
{
Cars.Add(
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}}"
Обновление разметки элементов управления