【问题标题】:Async ICommand implementation异步 ICommand 实现
【发布时间】:2017-07-31 11:18:53
【问题描述】:

当我在默认情况下尝试禁用命令时(即使没有传递 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;
}

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

现在我试着打电话

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

【问题讨论】:

  • Execute 在哪里发挥作用?
  • 您在何时何地设置CanExecutePredicate?
  • @AlessandroD'Andria 我没有设置它,它现在总是为空
  • @user3292642 抱歉,我不清楚您的问题是什么,我只能看到 CanExecutePredicate 可能存在竞争条件。
  • @AlessandroD'Andria 问题是我的 GUI 没有更新,即使我打电话给CanExecute(null);。你能详细说明一下可能的竞争条件吗?

标签: c# icommand


【解决方案1】:

在异步场景中,WPF 往往不知道何时检查 CanExecute,这就是为什么 Icommand 接口中有“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 状态。

【讨论】:

  • 与问题无关,但为什么(实际目的)在这里使用CommandManager?
  • 它用于让 wpf 了解您的具体命令,并告诉它在需要时刷新所有 CanExecute。这是 Prism 使用的框架,虽然我现在确实觉得它有点笨拙。这是一个更好的解释:joshsmithonwpf.wordpress.com/2008/06/17/…
猜你喜欢
  • 2021-01-18
  • 2010-11-30
  • 2011-01-09
  • 2018-03-29
  • 1970-01-01
  • 1970-01-01
  • 2013-10-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多