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

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;
}

我试图引入一个私有(private) 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);
}

最佳答案

在异步方案中,WPF往往不知道何时检查CanExecute,这就是为什么您在Icommand接口(interface)中具有“CanExecuteChanged”事件的原因。

您的命令实现中应该有以下内容:

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状态。

关于c# - 异步ICommand实现,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42712848/

10-13 09:46