В результате появляется возможность добавления автомобилей и обновления их цветов (пока с весьма ограниченной функциональностью) с помощью многократно используемого кода, содержащегося в автономных классах.
Изменение класса ChangeColorCommand
Финальным шагом будет обновление класса ChangeColorCommand
, чтобы он стал унаследованным от CommandBase
. Замените интерфейс ICommand
классом CommandBase
, добавьте к обоим методам ключевое слово override
и удалите код события CanExecuteChanged
. Все оказалось действительно настолько просто! Вот как выглядит новый код:
public class ChangeColorCommand : CommandBase
{
public override bool CanExecute(object parameter)
=> parameter is Car;
public override void Execute(object parameter)
{
((Car)parameter).Color = "Pink";
}
}
Объекты RelayCommand
Еще одной реализацией паттерна "Команда" (Command) в WPF является RelayCommand
. Вместо создания нового класса, представляющего каждую команду, данный паттерн применяет делегаты для реализации интерфейса ICommand
. Реализация легковесна в том, что каждая команда не имеет собственного класса. Объекты RelayCommand
обычно используются, когда нет необходимости в многократном применении реализации команды.
Создание базового класса RelayCommand
Как правило, объекты RelayCommand
реализуются в двух классах. Базовый класс RelayCommand
используется при отсутствии каких-либо параметров для методов CanExecute
и Execute
, а класс RelayCommand
применяется, когда требуется параметр. Начните с базового класса RelayCommand
, который задействует класс CommandBase
. Добавьте в папку Cmds
новый файл класса по имени RelayCommand.cs
. Сделайте его открытым и укажите CommandBase
в качестве базового класса. Добавьте две переменные уровня класса для хранения делегатов Execute
и CanExecute
:
private readonly Action _execute;
private readonly Func
Создайте три конструктора. Первый — стандартный конструктор (необходимый для производного класса RelayCommand
), второй — конструктор, который принимает параметр Action
, и третий — конструктор, принимающий параметры Action
и Func
:
public RelayCommand{}
public RelayCommand(Action execute) : this(execute, null) { }
public RelayCommand(Action execute, Func
{
_execute = execute
?? throw new ArgumentNullException(nameof(execute));
_canExecute = canExecute;
}
Наконец, реализуйте переопределенные версии CanExecute
и Execute
. Метод CanExecute
возвращает true
, если параметр Func
равен null
; если же параметр Func
не null
, то он выполняется и возвращается true
. Метод Execute
выполняет параметр типа Action
.
public override bool CanExecute(object parameter)
=> _canExecute == null || _canExecute;
public override void Execute(object parameter) { _execute; }
Создание класса RelayCommand
Добавьте в папку Cmds
новый файл класса по имени RelayCommandT.cs
. Класс RelayCommandT
является почти полной копией базового класса, исключая тот факт, что все делегаты принимают параметр. Сделайте класс открытым и обобщенным, а также унаследованным от базового класса RelayCommand
:
public class RelayCommand
Добавьте две переменные уровня класса для хранения делегатов Execute
и CanExecute
:
private readonly Action
private readonly Func
Создайте два конструктора. Первый из них принимает параметр Action
, а второй — параметры Action
и Func
:
public RelayCommand(Action
public RelayCommand(
Action
{
_execute = execute
?? throw new ArgumentNullException(nameof(execute));
_canExecute = canExecute;
}
Бьерн Страуструп , Бьёрн Страуструп , Валерий Федорович Альмухаметов , Ирина Сергеевна Козлова
Программирование, программы, базы данных / Базы данных / Программирование / Учебная и научная литература / Образование и наука / Книги по IT