我有一个简单的 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 处理此https://prismlibrary.github.io/docs/commanding.html的方式,但是它似乎他们也不支持异步 CanExecute 方法。
那么,有没有办法解决这个问题?或者在尝试使用 ICommand 从 CanExecute 运行 Async 方法时是否存在根本性的问题?