Расширение команды класса таким способом невозможно, насколько я могу судить, потому что Execute
не является виртуальным, и вы должны передать действие execute
конструктору. Во всяком случае, есть еще способ. Command
происходит от ICommand
, который имеет следующий интерфейс
public interface ICommand
{
event EventHandler CanExecuteChanged;
void Execute(object data);
bool CanExecute(object data);
}
. Вы можете создать класс AsyncBlockingCommand
(или любой другой), который будет возвращать соответствующее значение из CanExecute
в зависимости от того, Метод asyn c все еще работает (я знаю, что есть проблемы с async void
методами, поэтому обращайтесь с осторожностью)
public class AsyncBlockingCommand : ICommand
{
bool _canExecute = true;
Func<Task> _toExecute;
public AsyncBlockingCommand(Func<Task> toExecute)
{
_toExecute = toExecute;
}
public event EventHandler CanExecuteChanged;
public async void Execute(object data)
{
_canExecute = false;
RaiseCanExecuteChanged();
await _toExecute();
_canExecute = true;
RaiseCanExecuteChanged();
}
public bool CanExecute(object data) => _canExecute;
private void RaiseCanExecuteChanged()
{
CanExecuteChanged?.Invoke(this, EventArgs.Empty);
}
}
Перед выполнением вашего метода asyn c, устанавливается _canExecute
до false
и CanExecuteChanged
повышен. Таким образом, ваш Button
получит уведомление об изменении CanExecute
и отключится сам. И наоборот после вызова метода asyn c. (Возможно, RaiseCanExecuteChanged
нужно будет вызывать в главном потоке.)