private readonly Func _canExecute;

Создайте три конструктора. Первый — стандартный конструктор (необходимый для производного класса RelayCommand), второй — конструктор, который принимает параметр Action, и третий — конструктор, принимающий параметры Action и Func:

public RelayCommand(){}

public RelayCommand(Action execute) : this(execute, null) { }

public RelayCommand(Action execute, Func canExecute)

{

  _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(); }

<p id="AutBody_Root1300"><strong>Создание класса RelayCommand<t></t></strong></p>

Добавьте в папку Cmds новый файл класса по имени RelayCommandT.cs. Класс RelayCommandT является почти полной копией базового класса, исключая тот факт, что все делегаты принимают параметр. Сделайте класс открытым и обобщенным, а также унаследованным от базового класса RelayCommand:

public class RelayCommand : RelayCommand

Добавьте две переменные уровня класса для хранения делегатов Execute() и CanExecute():

private readonly Action _execute;

private readonly Func _canExecute;

Создайте два конструктора. Первый из них принимает параметр Action, а второй — параметры Action и Func:

public RelayCommand(Action execute):this(execute, null) {}

public RelayCommand(

  Action execute, Func canExecute)

  {

  _execute = execute

    ?? throw new ArgumentNullException(nameof(execute));

  _canExecute = canExecute;

}

Наконец, реализуйте переопределенные версии CanExecute() и Execute(). Метод CanExecute() возвращает true, если Func равно null, а иначе выполняет Func и возвращает true. Метод Execute() выполняет параметр типа Action.

public override bool CanExecute(object parameter)

  => _canExecute == null || _canExecute((T)parameter);

public override void Execute(object parameter)

  { _execute((T)parameter); }

<p id="AutBody_Root1301"><strong>Изменение файла MainWindow.xaml.cs</strong></p>

Когда используются объекты RelayCommand, при конструировании новой команды должны указываться все методы для делегатов. Это вовсе не означает, что код нуждается в помещении внутрь файла отделенного кода (как показано здесь); он просто должен быть доступным из файла отделенного кода. Код может находиться в другом классе (или даже в другой сборке), что дает преимущества инкапсуляции, связанные с созданием специального класса команды.

Добавьте новую закрытую переменную типа RelayCommand и открытое свойство по имени DeleteCarCmd;

private RelayCommand _deleteCarCommand = null;

public RelayCommand DeleteCarCmd

  => _deleteCarCommand ??=

     new RelayCommand(DeleteCar,CanDeleteCar));

Также потребуется создать методы DeleteCar() и CanDeleteCar():

private bool CanDeleteCar(Car car) => car != null;

private void DeleteCar(Car car)

{

  _cars.Remove(car);

}

Обратите внимание на строгую типизацию в методах — одно из преимуществ применения RelayCommand.

<p id="AutBody_Root1302"><strong>Добавление и реализация кнопки удаления записи об автомобиле</strong></p>

Последним шагом будет добавление кнопки Delete Car (Удалить автомобиль) и установка привязок Command и CommandParameter. Добавьте следующую разметку:

  Command="{Binding Path=DeleteCarCmd,

  RelativeSource={RelativeSource Mode=FindAncestor,

Перейти на страницу:

Похожие книги