T
はINotifyPropertyChanged
を実装している任意の型です。
ObservableCollection<T>
に格納されているデータについて、条件を満たす場合にtrue
、満たさない場合にfalse
を発行するIObservable<bool>
(正確にはReadOnlyReactiveProperty<bool>
)を作りたいです。
簡単にできると思ったのですがやり方がわからなかったので、わかる方は教えていただければ幸いです。
C#
1public class MyData : BindableBase 2{ 3 public string Id { get => _id; set => SetProperty(ref _id, value); } 4 private string _id; 5} 6 7public class MyDataUserViewModel 8{ 9 // 例:2文字以上の場合true 10 public ReactiveProperty<bool> IsLargeLength { get; } 11 public MyDataUserViewModel() 12 { 13 // 変換したいデータのObservableCollection 14 var collection = new ObservableCollection<MyData>(); 15 collection.AddRange(Enumerable.Range(1, 10). 16 Select(i => new MyData { Id = i.ToString() }).ToArray()); 17 18 // うまくいかなかった例 19 // Anyの時点でboolになるのでダメ 20 IsLargeLength = collection.Any(d => d.Length >= 2).ToReadOnlyReactiveProperty(); 21 // これだとReadOnlyにならない 22 IsLargeLength = collection. 23 ToReactivePropertySlimAsSynchronized(c => c.Any(d => d.Length >= 2)); 24 } 25}
言語:C# 9.0
https://docs.microsoft.com/ja-jp/dotnet/api/system.collections.objectmodel.observablecollection-1.collectionchanged?view=net-5.0
CollectionChanged から作ってみてください。
MyData のプロパティだけ変更される時には CollectionChanged は発生しないので、場合によっては要素全てを監視する必要があるかもしれません。
コメントありがとうございます。CollectionChangedを使って、コレクションの増減時にbool値が発行されるReactivePropertyは作ることができました。
ただ、要素数が変わらずにMyDataのプロパティの変更時にもIObservable<bool>の値を発行したいので、ToReacitve~~のように一発変換することはできなさそうです。おそらくReactiveProperty<bool>は普通にnewして、CollectionChangedと各要素の値変更をそれぞれSubscribeして必要があればReactiveProperty<bool>を変更するのが良さそうですが、もっといい方法がありますかね?
要素のプロパティの変化を知らなければならないのであれば、全ての要素を監視する以外にないと思います。
MyData をイミュータブルにできるのであれば、プロパティの変化の代わりに要素の取り替えが強制できるので、CollectionChanged で監視できます。
要素数が変わらなくても要素を取り替えれば発生するはずです。
なるほど、イミュータブルにして入れ替えさせるのは考えてなかったです。妙案ですね。
適当に回答を投稿してもらえればBAにしますが、どうしますか?
実装して意図通り動くことが確認できたら自己解決してください。
それまでにより良い回答がつくかもしれませんし。
わかりました。ありがとうございます。
ObserveElementProperty拡張メソッドがあるんですが、逆に増減時の扱いがよくわかんないです^^;
次の質問と関係あるんですよね?
それが解決すればこれも自動的に解決するってことですか?
イミュータブルに方針転換したということなんでしょうが、編集が前提のDataGridにrecordを使うのは明らかに筋が悪いと思います。
ZuishinさんもまさかMyDataをDataGridに突っ込むとは思っていないでしょう。
技術的興味があってやってみたいということであれば、なにもいうことはありませんが^^;
[C# - 完全コンストラクタパターンのコレクションをDataGridで編集するには|teratail](https://teratail.com/questions/305906#reply-429444
それよりもまずObserveElementPropertyを試してください。
完動コードを回答しているので5分で確認できると思うのですが。。。
たしかに表示専用ならDataGridでなくListViewでよかったかもしれません。
>次の質問と関係あるんですよね?
この質問は次のとは関係ありません。独立した質問です。
回答頂いている内容は確認ずみでした。BAつけるのを忘れていてすみません。
回答1件
あなたの回答
tips
プレビュー