Содержание
Команда не всегда может и должна выполняться. Например, если пользователь ввел некорректные данные, то команда на добавление этих данных, например, в БД должна быть отключена. Отключение команд в .NET MAUI осуществляется с использованием метода CanExecute()
.
Отключение команд в .NET MAUI
Итак, вернемся к нашему приложению. Напомню, как на данный момент организована модель представления с точки зрения механизма команд:
public class ProjectViewModel : INotifyPropertyChanged { //тут свойства и поля класса //весь исходный код класса можно найти здесь: https://csharp.webdelphi.ru/mvvm-v-net-maui-parametry-komandy/#i public ICommand AddCommand { get; set; } public ICommand RemoveCommand { get; set; } public ProjectViewModel() { AddCommand = new Command(() => { Project project = new() { Id = Projects.Count + 1, Name = this.Name, Description = this.Description, Author = this.Author }; Projects.Add(project); Id = -1; Name = string.Empty; Description = string.Empty; Author = string.Empty; }); RemoveCommand = new Command((param) => { if (param is Project proj) { Projects.Remove(proj); } }); } }
Как и говорилось ранее, конструктор класса Command
имеет несколько перегруженных версий. Более того, в .NET MAUI мы можем использовать универсальную версию этого класса. Изменим представленный выше код следующим образом:
public ICommand AddCommand { get; set; } public ICommand RemoveCommand { get; set; } public ProjectViewModel() { //команда добавления записи AddCommand = new Command(() => { Project project = new() { Id = Projects.Count + 1, Name = this.Name, Description = this.Description, Author = this.Author }; Projects.Add(project); Id = -1; Name = string.Empty; Description = string.Empty; Author = string.Empty; }, () => { return Name.Length > 2; }); //команда удаления записи RemoveCommand = new Command<Project>((param) => { Projects.Remove(param); }, (param) => { return param != null; }); }
Здесь для команды AddCommand
мы воспользовались второй версией конструктора класса Command
:
public Command(Action execute, Func<bool> canExecute)
execute
— делегат для выполнения задачиcanExecute
— делегат для проверки возможности выполнения задачи
Второй параметр конструктора (canExecute
) проверяет длину имени проекта и, если она более двух символов, то считается, что команда может выполняться.
для команды RemoveCommand
мы воспользовались универсальной версией класса Command
. Теперь нам нет необходимости проверять тип параметра — мы точно знаем, что это будет Project
. Отключение этой команды произойдет, если параметр будет равен null
:
(param) => { return param != null; }
Проверим работу приложения. Смотрим внимательно на gif-ку ниже:
Как можно видеть, несмотря на то, что мы определили условие при котором команда
AddCommand
может выполняться, отключение команды не происходит — она остается активной и позволяет добавить ошибочные данные в список. При этом, команда RemoveCommand
работает правильно — она неактивна до тех пор, пока мы не выберем что-то в списке. Дело в том, что свойство Name нашего класса, от которого зависит активность команды AddCommand, может меняться по мере работы приложения и для того, чтобы активность команды поменялась, мы должны оповестить систему вручную. И для этого нам пригодится метод ChangeCanExecute()
класса Command
. Изменим метод OnPropertyChanged() нашего класса следующим образом
public void OnPropertyChanged([CallerMemberName] string prop = "") { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(prop)); ((Command)AddCommand).ChangeCanExecute(); }
Теперь система будет знать, что произошли какие-то изменения, которые могут повлиять на активность команды AddCommand
. Запустим приложение и проверим результат:
Как видите, теперь наши команды правильно реагируют на изменение тех или иных свойств и данных в приложении.
Итого
Отключение команд в .NET MAUI помогает нам избежать ввода неверных данных в приложение. Для возможности отключения команд используется метод CanExecute() задать который можно с использованием второй версии конструктора класса Command, передав в качестве второго параметра делегат типа Func<bool>. Для оповещения системы о возможности отмены команды используется метод ChangeCanExecute()
класса Command