c# - 使用 WhenAnyObservable 组合和过滤多个事件
问题描述
我有一个 ViewModel:
- 一个列表 ReactiveList<MyObject>
- 单个 MyObject
- IsBusy 布尔值
当 MyObject 列表或单个 MyObject 中的“Active”属性都不为真时,或者在任何情况下 IsBusy 为真时,我想禁用该命令。
在将 IsBusy 添加到图片之前,我想出的最佳解决方案是:
var canSave = this.WhenAnyObservable(
x => x.MyObjectsList.ItemChanged, x => x.MyObject.Changed)
.Where(x => x.PropertyName == "Active")
.Select(_ => MyObjectsList.Any(x => x.Active) || MyObject.Active);
SaveCommand = ReactiveCommand.Create(Save, canSave);
这个想法是每次 Active 属性更改时都会重新评估。不确定这是否是最好的解决方案(因此欢迎任何改进它的建议),但我绝对无法将 IsBusy 添加到图片中,以便在 IsBusy 时重新评估 Select 子句(包括 IsBusy 状态)变化。
解决方案
我认为您的答案可以简化。
var itemChangedObs = this.WhenAnyValue(x => x.MyObject.Active);
var isBusyObs = this.WhenAnyValue(x => x.IsBusy);
var listItemChangedObs = this.WhenAnyObservable(x => x.MyObectsList.ItemChanged).Where(x => x.PropertyName == "Active").Select(_ => MyObjectsList.Any(x => x.Active)).StartsWith(false)
var canRunCommand = itemChangedObs.CombineLatest(listItemChangedObs, isBusyObs, (itemActive, listItemActive, isBusy) => (itemActive || listItemActive) && !isBusy);
这个版本本质上使用了一个 CombineLatest,它在将两个 observables 组合在一起后接受你想要的值的 Lambda。
CombineLatest() 在两个 Observable 都发出值之前不会产生值,因此 listItemChanged 在前面有一个 StartsWith(false) 。
默认情况下,WhenAnyValue() 将始终发出该值的 default(T) 作为其初始值,因此您不需要带有这些语句的 StartsWith。
推荐阅读
- sql-server - 在 debian 10 服务器上配置团队基础服务器备份到 samba 共享路径时出错
- java - 我正在运行 mvn 全新安装。检查代理,镜像,安装的证书仍然没有解决
- .net - 图例显示不正确
- excel - 从特定表中抓取数据
- .htaccess - .htaccess 将二级页面重定向到三级页面
- python - 如何在另一列中使用权重进行交叉表?
- django - Django CSRF 令牌丢失或不正确,但已添加 CSFR
- python - 根据数据框列中的值将 2-D numpy 数组重构为 3-D numpy 数组
- if-statement - 是否可以在 Kotlin 的“if”条件内声明一个变量?
- python - 将时间列绘制为 x 轴刻度时出错