I found three different solutions to call my command's CanExecute
and Execute
methods like I could before in ReactiveUI 6.5:
Option 1
This is equal to the call in version 6.5, but we need to explicitly convert the command to an ICommand:
if (((ICommand) command).CanExecute(null))
command.Execute().Subscribe();
Option 2
if(command.CanExecute.FirstAsync().Wait())
command.Execute().Subscribe()
or the async variant:
if(await command.CanExecute.FirstAsync())
await command.Execute()
Option 3
Another option is to make us of the InvokeCommand
extension method.
Observable.Start(() => {}).InvokeCommand(ViewModel, vm => vm.MyCommand);
This respects the command's executability, like mentioned in the documentation.
In order to make it more comfortable I've written a small extension method to provide a ExecuteIfPossible
and a GetCanExecute
method:
public static class ReactiveUiExtensions
{
public static IObservable<bool> ExecuteIfPossible<TParam, TResult>(this ReactiveCommand<TParam, TResult> cmd) =>
cmd.CanExecute.FirstAsync().Where(can => can).Do(async _ => await cmd.Execute());
public static bool GetCanExecute<TParam, TResult>(this ReactiveCommand<TParam, TResult> cmd) =>
cmd.CanExecute.FirstAsync().Wait();
}
You can use this extension method as follows:
command.ExecuteIfPossible().Subscribe();
Note: You need the Subscribe()
call at the end, just like you need it for the call to Execute()
, otherwise nothing will happen.
Or if you want to use async and await:
await command.ExecuteIfPossible();
If you want to check if a command can be executed, just call
command.GetCanExecute()