ObservableCollection内の特定の要素を集計して、ReavtiveProperty化する方法のメモ
やりかたがずっとわからなかったんですが、Gistにやりたかったことと同様な実装をされた方がおられたのでようやく解決。
ReactivePropertyでObservableCollection中の要素のPropertyを購読したい。
実装も上記のものとほぼ同じなんですが、若干仕様が変わっていたためやりかたを備忘録として残しておきます。
検証環境
- ReactiveProperty 3.6.0
実装例
やりたいことは単純で、特定のリストの各要素の更新フラグを監視して、どれかか一つでも更新されていたら親要素の更新フラグも有効化するというものです。逆にすべて保存されていたら自動的に無効化もされます。
public ObservableCollection<Hoge> Items { get; } = new ObservableCollection<Hoge>();
public ReactiveProperty<bool> IsUpdated { get; }
...
IsUpdated = Items
.ObserveElementProperty(x => x.IsUpdated)
.Scan(0, (counter, x) => counter + (x.Value ? 1 : (0 < counter ? -1 : 0)))
.Select(counter => 0 < counter)
.ToReactiveProperty();
この実装のポイントは Scan
かと思います。Scan(初期値, (前回値, 次の値) => { return 計算結果; })
で集計ができるかんじのようです。便利。
Reactive Extensions入門 13「値を集めて回る」 - かずきのBlog@hatena
Rxにおけるscanとreduceの違い - Qiita
注意点
注意点として、Gistで公開されていたものとは以下が仕様が変わっていました。
.Scan(0, (counter, x) => counter + (x ? 1 : (0 < counter ? -1 : 0)))
.Scan(0, (counter, x) => counter + (x.Value ? 1 : (0 < counter ? -1 : 0)))
どうも ReactiveProperty の v2.1.3 から破壊的な変更が入っているらしいです。
ReactiveProperty v2.1.3をリリースしました - かずきのBlog@hatena
参考
ReactivePropertyでObservableCollection中の要素のPropertyを購読したい。
ReactiveProperty v2.1.3をリリースしました - かずきのBlog@hatena