异步ICommand实现

时间:2017-03-10 07:38:49

标签: c# icommand

当我尝试在默认情况下执行命令时禁用命令(即使没有传递CanExecute谓词)时,我的asny ICommand实现面临一种奇怪的行为。

public bool CanExecute(object parameter)
{
  if (CanExecutePredicate == null)
  {
    return !mIsExecuting;
  }

  return !mIsExecuting && CanExecutePredicate(parameter);
}

public async void Execute(object parameter)
{
  mIsExecuting = true;
  await ExecuteAsync(parameter);
  mIsExecuting = false;
}

我尝试引入一个私有bool,我在执行之前设置为true,之后设置为false。执行完成后会设置bool,但只有在单击鼠标按钮或移动鼠标或w / e后才会调用CanExecute。

现在我试着打电话

CanExecute(null);

之后

mIsExecuting = false;

但这对两者都没有帮助。我不知道我错过了什么。

感谢您的帮助

编辑:

为了澄清我添加了这个类的构造函数:

 public AsyncRelayCommand(Func<object, Task> execute)
  : this(execute, null)
{
}

public AsyncRelayCommand(Func<object, Task> asyncExecute,
               Predicate<object> canExecutePredicate)
{
  AsyncExecute = asyncExecute;
  CanExecutePredicate = canExecutePredicate;
}

protected virtual async Task ExecuteAsync(object parameter)
{
  await AsyncExecute(parameter);
}

1 个答案:

答案 0 :(得分:5)

在异步方案中,WPF往往不知道何时检查CanExecute,这就是为什么你有&#34; CanExecuteChanged&#34; Icommand界面中的事件。

你的命令实现应该有这样的东西:

public event EventHandler CanExecuteChanged
{
    add { CommandManager.RequerySuggested += value; }

    remove { CommandManager.RequerySuggested -= value; }
}

public void RaiseCanExecuteChanged()
{
    CommandManager.InvalidateRequerySuggested();
}

使用上面的代码,您现在可以执行此操作:

public async void Execute(object parameter)
{
    mIsExecuting = true;

    RaiseCanExecuteChanged ( ); // Not necessary if Execute is not called locally

    await ExecuteAsync(parameter);
    mIsExecuting = false;

    RaiseCanExecuteChanged ( );
}

这将告诉WPF您要刷新CanExecute命令状态。