Язык программирования C#9 и платформа .NET5
Наконец, реализуйте переопределенные версии
иCanExecute(). МетодExecute()возвращаетCanExecute(), еслиtrueравноFunc, а иначе выполняетnullи возвращаетFunc. Методtrueвыполняет параметр типаExecute().Actionpublic override bool CanExecute(object parameter)=> _canExecute == null || _canExecute((T)parameter);public override void Execute(object parameter){ _execute((T)parameter); }Изменение файла MainWindow.xaml.cs
Когда используются объекты
, при конструировании новой команды должны указываться все методы для делегатов. Это вовсе не означает, что код нуждается в помещении внутрь файла отделенного кода (как показано здесь); он просто должен быть доступным из файла отделенного кода. Код может находиться в другом классе (или даже в другой сборке), что дает преимущества инкапсуляции, связанные с созданием специального класса команды.RelayCommandДобавьте новую закрытую переменную типа
и открытое свойство по имениRelayCommand<Car>;DeleteCarCmdprivate RelayCommand<Car> _deleteCarCommand = null;public RelayCommand<Car> DeleteCarCmd=> _deleteCarCommand ??=new RelayCommand<Car>(DeleteCar,CanDeleteCar));Также потребуется создать методы
иDeleteCar():CanDeleteCar()private bool CanDeleteCar(Car car) => car != null;private void DeleteCar(Car car){_cars.Remove(car);}Обратите внимание на строгую типизацию в методах — одно из преимуществ применения
.RelayCommand<T>Добавление и реализация кнопки удаления записи об автомобиле
Последним шагом будет добавление кнопки Delete Car (Удалить автомобиль) и установка привязок
иCommand. Добавьте следующую разметку:CommandParameter<Button x:Name="btnDeleteCar" Content="Delete Car" Margin="5,0,5,0" Padding="4, 2"Command="{Binding Path=DeleteCarCmd,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Window}}}"CommandParameter="{Binding ElementName=cboCars, Path=SelectedItem}"/>Теперь, запустив приложение, вы можете удостовериться в том, что кнопка Delete Car доступна, только если в раскрывающемся списке выбран автомобиль, и щелчок на ней приводит к удалению записи об автомобиле.
Итоговые сведения о командах
На этом краткий экскурс в команды WPF завершен. За счет перемещения кода обработки событий из файла отделенного кода в индивидуальные классы команд появляются преимущества инкапсуляции, многократного использования и улучшенной возможности сопровождения. Если настолько большое разделение обязанностей не требуется, тогда можно применять легковесную реализацию
. Цель заключается в том, чтобы улучшить возможность сопровождения и качество кода, так что выбирайте подход, который лучше подходит для вашей ситуации.RelayCommandПеренос кода и данных в модель представления
Как и в разделе "Проверка достоверности WPF", вы можете продолжить работу с тем же самым проектом или создать новый и скопировать в него весь код. Вы создадите новый проект по имени
. В случае работы с проектом из предыдущего раздела обращайте внимание на пространства имен в примерах кода и корректируйте их по мере необходимости.WpfViewModelСоздайте в проекте новую папку под названием
и поместите в нее новый файл классаViewModels. Добавьте операторыMainWindowViewModel.csдля следующих пространств имен и сделайте класс открытым:usingusing System.Collections.Generic;using System.Collections.ObjectModel;using System.Windows.Input;using WpfViewModel.Cmds;using WpfViewModel.Models;На заметку! Популярное соглашение предусматривает именование моделей представлений в соответствие с окном, которое их поддерживает. Обычно имеет смысл следовать такому соглашению, поэтому оно соблюдается в настоящей главе. Тем не менее, как и любой паттерн или соглашение, это не норма, и на данный счет вы найдете широкий спектр мнений.
Перенос кода MainWindow.xaml.cs
В модель представления будет перемещен почти весь код из файла отделенного кода. В конце останется только несколько строк, включая вызов метода
и код установки контекста данных для окна в модель представления.InitializeComponent()Создайте открытое свойство типа
по имениIList<Car>:Carspublic IList<Car> Cars { get; } =new ObservableCollection<Car>();Создайте стандартный конструктор и перенесите в него весь код создания объектов
из файлаCar, обновив имя списковой переменной. Можете также удалить переменнуюMainWindow.xaml.csиз_cars. Ниже показан конструктор модели представления:MainWindow.xaml.cspublic MainWindowViewModel(){Cars.Add(