Reputation: 1681
I am using the @Stephen-Cleary AsyncCommand implementation in WPF (.NET 4.0) and now I am trying to find out how to specify the CanExecute handler during command definition.
Usually I create the command like this:
SaveCommandAsync = AsyncCommand.Create(async token =>
{
//async code
});
I don't see any Create overload so I can specify CanExecute logic.
Thank you,
Igor
Upvotes: 4
Views: 920
Reputation: 306
Just for update this topic.
Currently actual reference implementation of AsyncCommand is in CommunityToolkit.Mvvm.Input project that could be referenced with apropriate NuGet. And in code it could be written something like this:
// 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; }
Make attention that CanExecute do not enables or disables a button that have a binding to apropriate Command. It just enables execution of a Command. In case if you want to represent a CanExecute by enabling or disabling a button, you could use something like the following in your XAML:
<Button
Content="Click me!"
Command="{Binding MyCommand}"
IsEnabled="{Binding MyCommand.IsRunning, Converter={StaticResource InverseBooleanConverter}, Mode=OneWay}"/>
Implementation of a InverseBooleanConverter you could find in other answers. Or you could see a full code of a demo project WpfAsyncCommandExample
Upvotes: 1
Reputation: 3885
Use Stephen Cleary's Nito.Mvvm.Async project to achieve what you need.
Add nuget reference to the package:
<package id="Nito.Mvvm.Async" version="1.0.0-eta-05" targetFramework="net45" />
Create Xaml binding:
<Button Content="Toggle" Command="{Binding MyAsyncCommand}"></Button>
Create CustomAsyncCommand, specifying CanExecute function
MyAsyncCommand = new CustomAsyncCommand(AsyncAction, x=> !_isWorking);
Do some async work in AsyncAction
private async Task AsyncAction(object obj) {
_isWorking = true;
MyAsyncCommand.OnCanExecuteChanged();
await Task.Delay(2000);
_isWorking = false;
MyAsyncCommand.OnCanExecuteChanged();
}
And finally: enjoy.
Upvotes: 6