如何直接调用ReactiveUI 7中的ReactiveCommand.Execute()是否正确?

时间:2016-11-29 09:21:55

标签: c# reactiveui

我正在尝试将我的项目从ReactiveUI 6.5转换为版本7.在旧版本中,我调用了

// var command = ReactiveCommand.Create...;
// ...
if(command.CanExecute(null))
    command.Execute(null);

为了从我后面的代码执行命令。

现在,CanExecute方法不再可用,并替换为IObservable<bool>属性。如果我只是打电话给Execute().Subscribe()或者我必须明确地调用它,是否会自动调用CanExecute Observable?

现在我用

替换了上面的代码
command.Execute().Subscribe();

1 个答案:

答案 0 :(得分:12)

我找到了三种不同的解决方案来调用我的命令的CanExecuteExecute方法,就像我之前在ReactiveUI 6.5中那样:

选项1

这与版本6.5中的调用相同,但我们需要将命令显式转换为ICommand:

if (((ICommand) command).CanExecute(null))
    command.Execute().Subscribe();

选项2

if(command.CanExecute.FirstAsync().Wait())
    command.Execute().Subscribe()

或异步变体:

if(await command.CanExecute.FirstAsync())
    await command.Execute()

选项3

另一个选择是让我们使用InvokeCommand扩展方法。

Observable.Start(() => {}).InvokeCommand(ViewModel, vm => vm.MyCommand);

这尊重命令的可执行性,如documentation中所述。

为了让它更舒服,我编写了一个小扩展方法来提供ExecuteIfPossibleGetCanExecute方法:

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

您可以按如下方式使用此扩展方法:

command.ExecuteIfPossible().Subscribe();

注意:您最后需要Subscribe()来电,就像您需要拨打Execute()一样,否则不会发生任何事情。

或者如果你想使用async并等待:

await command.ExecuteIfPossible();

如果要检查命令是否可以执行,只需调用

command.GetCanExecute()