我正在尝试将我的项目从ReactiveUI 6.5转换为版本7.在旧版本中我调用了
// var command = ReactiveCommand.Create...; // ... if(command.CanExecute(null)) command.Execute(null);
现在,CanExecute方法不再可用,并替换为IObservable< bool>的属性.如果我只是调用Execute(),是否会自动调用CanExecute Observable.Subify()或者我必须显式调用它吗?@H_403_5@
command.Execute().Subscribe();
解决方法
我找到了三种不同的解决方案来调用我的命令的CanExecute和Execute方法,就像我之前在ReactiveUI 6.5中那样:
选项1@H_403_5@
这等于6.5版本中的调用,但我们需要将命令显式转换为ICommand:@H_403_5@
if (((ICommand) command).CanExecute(null)) command.Execute().Subscribe();
选项2@H_403_5@
if(command.CanExecute.FirstAsync().Wait()) command.Execute().Subscribe()
或异步变体:@H_403_5@
if(await command.CanExecute.FirstAsync()) await command.Execute()
选项3@H_403_5@
另一个选择是使我们使用InvokeCommand扩展方法.@H_403_5@
Observable.Start(() => {}).InvokeCommand(viewmodel,vm => vm.MyCommand);
这尊重命令的可执行性,如documentation中所述.@H_403_5@
为了让它更舒服,我编写了一个小扩展方法来提供ExecuteIfPossible和GetCanExecute方法:@H_403_5@
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> cmd) => cmd.CanExecute.FirstAsync().Wait(); }
command.ExecuteIfPossible().Subscribe();
注意:你需要在最后调用Subscribe(),就像你需要它来调用Execute()一样,否则什么都不会发生.@H_403_5@
或者如果你想使用async并等待:@H_403_5@
await command.ExecuteIfPossible();
command.GetCanExecute()