У меня есть простой класс DelegateCommand, который выглядит следующим образом:
public class DelegateCommand<T> : System.Windows.Input.ICommand where T : class
{
public event EventHandler CanExecuteChanged;
private readonly Predicate<T> _canExecute;
private readonly Action<T> _execute;
public DelegateCommand(Action<T> execute) : this(execute, null)
{
}
public DelegateCommand(Action<T> execute, Predicate<T> canExecute)
{
this._execute = execute;
this._canExecute = canExecute;
}
public bool CanExecute(object parameter)
{
if (this._canExecute == null)
return true;
return this._canExecute((T)parameter);
}
public void Execute(object parameter)
{
this._execute((T)parameter);
}
public void RaiseCanExecuteChanged()
{
this.CanExecuteChanged?.Invoke(this, EventArgs.Empty);
}
}
Я использую GalaSoft.MvvmLight
для проверки, и обычно я просто делаю что-то подобное в конструкторе View:
this.MyCommand = new DelegateCommand<object>(o => {
//Do execute stuff
}, o =>
{
//Do CanExecute stuff
var validateResult = this.Validator.ValidateAll();
return validateResult.IsValid;
});
public DelegateCommand<object> MyCommand { get; }
Все это прекрасно работает, когда у меня есть простая проверка, например:
this.Validator.AddRequiredRule(() => this.SomeProperty, "You must select.......");
, но теперь мне нужен метод проверки, который выполняет долго выполняющуюся задачу (в моем случае вызов WebService), поэтому, когда яхочу сделать что-то вроде этого:
this.Validator.AddAsyncRule(async () =>
{
//Long running webservice call....
return RuleResult.Assert(true, "Some message");
});
и, следовательно, объявить команду следующим образом:
this.MyCommand = new DelegateCommand<object>(o => {
//Do execute stuff
}, async o =>
{
//Do CanExecute ASYNC stuff
var validateResult = await this.Validator.ValidateAllAsync();
return validateResult.IsValid;
});
Я немного расстроен, потому что стандартная реализация ICommand не делаетпохоже, имеют дело с асинхронными сценариями.
Не слишком задумываясь, кажется, что вы могли бы потенциально переписать класс DelegateCommand для поддержки такой функциональности, но я смотрел на то, как Prism работает с этим * 1020.* Однако кажется, что они также НЕ поддерживают асинхронные методы CanExecute.
Итак, есть ли способ обойти эту проблему?Или что-то принципиально не работает при попытке запустить метод Async из CanExecute с использованием ICommand?