ReactiveUI实现ReactiveCommand互斥执行及Observable<bool>取反问题
AvaloniaUI中ReactiveCommand互斥执行及Observable反转问题
问题1:解决命令互斥执行的异常及正确实现
错误原因分析
你当前的实现存在几个问题:
- 拼写错误:
x => x.MyCommand11.IsExecuting中的MyCommand11是笔误,应为MyCommand1 - 初始化顺序问题:构造函数中先尝试通过
WhenAnyObservable监听命令的IsExecuting,但此时MyCommand1/2/3还未完成初始化,导致NotSupportedException - 逻辑反转:ReactiveCommand的可执行条件需要的是「当前命令可以执行的条件」,你传入的
IsAnyCommandIsExecuting表示「有任意命令在执行」,这会导致命令在有其他命令执行时才可用,完全违背需求 - Observable组合方式错误:
WhenAnyObservable会合并多个Observable的发射值,但无法直接判断「是否有任意一个命令在执行」,需要用CombineLatest来合并所有执行状态并进行逻辑判断
正确实现代码
public class MyClass { public ReactiveCommand<Unit, Unit> MyCommand1 { get; } public ReactiveCommand<Unit, Unit> MyCommand2 { get; } public ReactiveCommand<Unit, Unit> MyCommand3 { get; } public MyClass() { // 先初始化所有命令(暂时不带可执行条件) MyCommand1 = ReactiveCommand.CreateFromTask(MyMethod1); MyCommand2 = ReactiveCommand.CreateFromTask(MyMethod2); MyCommand3 = ReactiveCommand.CreateFromTask(MyMethod3); // 创建可执行条件:当所有命令都未处于执行状态时,返回true var canExecute = Observable.CombineLatest( MyCommand1.IsExecuting, MyCommand2.IsExecuting, MyCommand3.IsExecuting, (exec1, exec2, exec3) => !exec1 && !exec2 && !exec3); // 为每个命令添加可执行条件 MyCommand1.AddCanExecuteCondition(canExecute); MyCommand2.AddCanExecuteCondition(canExecute); MyCommand3.AddCanExecuteCondition(canExecute); } private Task MyMethod1() => Task.Delay(1000); private Task MyMethod2() => Task.Delay(1000); private Task MyMethod3() => Task.Delay(1000); }
问题2:反转Observable的最优方式
直接使用Select操作符对每个发射值取反即可,这是最简洁高效的方案:
// 假设original是你需要反转的Observable<bool> var reversedObservable = original.Select(value => !value);
比如针对问题1中的场景,若先得到「有任意命令在执行」的Observable,再反转得到所有命令都未执行的条件:
var isAnyCommandExecuting = Observable.CombineLatest( MyCommand1.IsExecuting, MyCommand2.IsExecuting, MyCommand3.IsExecuting, (e1, e2, e3) => e1 || e2 || e3); // 反转得到所有命令都未执行的条件 var canExecute = isAnyCommandExecuting.Select(v => !v);
内容的提问来源于stack exchange,提问作者sausage_mouse
相关产品推荐
相关产品推荐

