异步命令的CanExecute处理程序

4

我正在使用@Stephen-Cleary的AsyncCommand实现在WPF(.NET 4.0)中,现在我正在尝试找出如何在命令定义期间指定CanExecute处理程序。

通常我会像这样创建命令:

            SaveCommandAsync = AsyncCommand.Create(async token =>
            {
                //async code    
            });

我没有看到任何创建重载,因此无法指定CanExecute逻辑。
谢谢,
Igor

请发布所提到实现的链接。 - 3615
这是一个非常流行的异步命令实现(链接在问题中)在网络上有很多参考资料,但我找不到任何示例或如何指定CanExecute行为。 - Igor Kondrasovas
我认为那篇文章的源代码是用于教育目的的,它旨在展示方法,而不是在实际应用中直接使用。相反,我建议查看他在Github上的库。如果你真的想保留那个实现,可以尝试继承AsyncCommand并覆盖CanExecute。 - 3615
我正在使用GitHub的感谢(但不是.NET Core版本),因为我针对的是.NET 4.0。问题是CanExecute逻辑取决于每个命令,因此我需要一个谓词,类似于RelayCommand。有什么想法吗? - Igor Kondrasovas
2个回答

6

使用Stephen Cleary的Nito.Mvvm.Async项目,实现您所需的功能。

将nuget引用添加到中: <package id="Nito.Mvvm.Async" version="1.0.0-eta-05" targetFramework="net45" />

创建Xaml绑定:

<Button Content="Toggle" Command="{Binding MyAsyncCommand}"></Button>

创建CustomAsyncCommand,并指定CanExecute函数

MyAsyncCommand = new CustomAsyncCommand(AsyncAction, x=> !_isWorking);

在AsyncAction中进行一些异步工作

private async Task AsyncAction(object obj) {
    _isWorking = true;
    MyAsyncCommand.OnCanExecuteChanged();
    await Task.Delay(2000);
    _isWorking = false;
    MyAsyncCommand.OnCanExecuteChanged();
}

最后: 享受

很好的问题。几个月前,我不得不从.NET 4.5降级到4.0,所以我通过Microsoft.Bcl.Async NuGet包得到了救赎。 - Igor Kondrasovas
当然对我来说是这样,也可能对其他人有用!谢谢! - Igor Kondrasovas
感谢@3615的支持。看起来这个方法很不错。我还需要几天时间在我的端上进行测试,然后会告诉你结果。 - Igor Kondrasovas
我对此感到困惑,似乎在某个时候该方法已更改为受保护状态:https://github.com/StephenCleary/Mvvm.Async/blob/eea676b1f23881b4c755cc78dca4094928a59127/src/Nito.Mvvm.Async/AsyncCommandBase.cs#L40因此,我不确定它如何支持CanExecuteChanged? - OwenP
@OwenP 你正在查看基类,而实现中有OnCanExecuteChanged公共方法。请参考链接:https://github.com/StephenCleary/Mvvm.Async/blob/eea676b1f23881b4c755cc78dca4094928a59127/src/Nito.Mvvm.Async/CustomAsyncCommand.cs#L116 - 3615
显示剩余5条评论

1

仅为更新此主题。

目前AsyncCommand的实际参考实现在CommunityToolkit.Mvvm.Input项目中,可以通过适当的NuGet引用。在代码中,可以这样编写:

// In properties declaration
public IAsyncRelayCommand MyCommand { get; }
// In ctor
MyCommand = new AsyncRelayCommand(MyAction, () => MyCanExecute());
// Action declaration
private async Task MyAction() // Also could be a (CancellationToken token)
{ }
// Can exectute declaration
private bool DownloadTextCanExecute()
{ return !MyCommand.IsRunning; }

请注意,CanExecute不会启用或禁用与适当命令绑定的按钮。它只是启用命令的执行。如果您想通过启用或禁用按钮来表示CanExecute,则可以在XAML中使用以下内容: ```XAML

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接