前提
https://okazuki.jp/ReactiveProperty/features/Collections.html
リンク先を参考に、ObservableCollectionからToReadOnlyReactiveCollectionを使ってツリーを生成しようとしています。
(ObservableCollectionの追加・削除があったらツリーにも同期するように)
根本的な考え方など誤っていましたら、その辺りからご指摘もらえると嬉しいです。
該当のソースコード・試したこと
次のような感じで実装してみました。
cs
1using System.Collections.ObjectModel; 2using System.Text.Json; 3using Reactive.Bindings; 4 5var collection = new ObservableCollection<TestItem> 6{ 7 new TestItem { Category1 = "C11", Category2 = "C21", Category3 = "C31", Name = "Name01", }, 8 new TestItem { Category1 = "C11", Category2 = "C21", Category3 = "C31", Name = "Name02", }, 9 new TestItem { Category1 = "C11", Category2 = "C21", Category3 = "C31", Name = "Name03", }, 10 new TestItem { Category1 = "C11", Category2 = "C21", Category3 = "C32", Name = "Name04", }, 11 new TestItem { Category1 = "C11", Category2 = "C21", Category3 = "C32", Name = "Name05", }, 12 new TestItem { Category1 = "C11", Category2 = "C21", Category3 = "C33", Name = "Name06", }, 13 new TestItem { Category1 = "C11", Category2 = "C22", Category3 = "C31", Name = "Name07", }, 14 new TestItem { Category1 = "C11", Category2 = "C22", Category3 = "C32", Name = "Name08", }, 15 new TestItem { Category1 = "C12", Category2 = "C21", Category3 = "C31", Name = "Name09", }, 16}; 17var top = new TreeItem { Category = "top" }; 18_ = collection.ToReadOnlyReactiveCollection(x => 19{ 20 var c1 = top.Children.Where(y => y.Category == x.Category1); 21 var c2 = c1.SelectMany(y => y.Children).Where(y => y.Category == x.Category2); 22 var c3 = c2.SelectMany(y => y.Children).Where(y => y.Category == x.Category3); 23 if (!c1.Any()) 24 { 25 top.Children.Add(new TreeItem { Category = x.Category1 }); 26 } 27 if (!c2.Any()) 28 { 29 var item = c1.Single(); 30 item.Children.Add(new TreeItem { Category = x.Category2 }); 31 } 32 if (!c3.Any()) 33 { 34 var item = c2.Single(); 35 item.Children.Add(new TreeItem { Category = x.Category3 }); 36 } 37 return x; 38}); 39collection.Add(new TestItem { Category1 = "C11", Category2 = "C21", Category3 = "C31", Name = "Name11", }); 40collection.Add(new TestItem { Category1 = "C11", Category2 = "C21", Category3 = "C34", Name = "Name12", }); 41collection.Remove(collection.Single(x => x.Name == "Name07")); // 削除した時にToReadOnlyReactiveCollectionの中のラムダ式が呼び出されません 42Console.WriteLine(JsonSerializer.Serialize(top)); 43 44class TestItem 45{ 46 public string Category1 { get; set; } = ""; 47 public string Category2 { get; set; } = ""; 48 public string Category3 { get; set; } = ""; 49 public string Name { get; set; } = ""; 50} 51class TreeItem 52{ 53 public string Category { get; set; } = ""; 54 public ObservableCollection<TreeItem> Children { get; set; } = new ObservableCollection<TreeItem>(); 55} 56
ToReadOnlyReactiveCollectionの戻りを破棄してしまっているので、正しい使い方ではないような気がしています。
(ToReadOnlyReactiveCollectionの1つ目の引数がconverter
という名前からも正しい使い方ではないような気がしています)
現在は、ObservableCollectionの追加・削除が同期できるところを目指していますが、
この先、ObserveElementPropertyChangedと組み合わせて、
ObservableCollectionの要素の分類が変更された場合にもツリーに同期したいと思っています。
(「ObserveElementPropertyChanged」は https://qiita.com/okazuki/items/6faac7cb1a7d8a6ad0f2 で知りました)
発生している問題・エラーメッセージ
ObservableCollectionからRemoveしてもツリーから削除されません。
現在の結果は次の通りです。
Name07を削除しましたが、大分類「C11」、中分類「C22」、小分類「C31」が削除されません。
json
1{ 2 "Category": "top", 3 "Children": [ 4 { 5 "Category": "C11", 6 "Children": [ 7 { 8 "Category": "C21", 9 "Children": [ 10 { 11 "Category": "C31", 12 "Children": [] 13 }, 14 { 15 "Category": "C32", 16 "Children": [] 17 }, 18 { 19 "Category": "C33", 20 "Children": [] 21 }, 22 { 23 "Category": "C34", 24 "Children": [] 25 } 26 ] 27 }, 28 { 29 "Category": "C22", 30 "Children": [ 31 { 32 "Category": "C31", 33 "Children": [] 34 }, 35 { 36 "Category": "C32", 37 "Children": [] 38 } 39 ] 40 } 41 ] 42 }, 43 { 44 "Category": "C12", 45 "Children": [ 46 { 47 "Category": "C21", 48 "Children": [ 49 { 50 "Category": "C31", 51 "Children": [] 52 } 53 ] 54 } 55 ] 56 } 57 ] 58}
期待する結果は次の通りです。
json
1{ 2 "Category": "top", 3 "Children": [ 4 { 5 "Category": "C11", 6 "Children": [ 7 { 8 "Category": "C21", 9 "Children": [ 10 { 11 "Category": "C31", 12 "Children": [] 13 }, 14 { 15 "Category": "C32", 16 "Children": [] 17 }, 18 { 19 "Category": "C33", 20 "Children": [] 21 }, 22 { 23 "Category": "C34", 24 "Children": [] 25 } 26 ] 27 }, 28 { 29 "Category": "C22", 30 "Children": [ 31 { 32 "Category": "C32", 33 "Children": [] 34 } 35 ] 36 } 37 ] 38 }, 39 { 40 "Category": "C12", 41 "Children": [ 42 { 43 "Category": "C21", 44 "Children": [ 45 { 46 "Category": "C31", 47 "Children": [] 48 } 49 ] 50 } 51 ] 52 } 53 ] 54}
補足情報(FW/ツールのバージョンなど)
- .NET 6
- "ReactiveProperty" Version="8.0.5"
- "PropertyChanged.Fody" Version="3.4.0"
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2022/04/27 03:30
2022/04/27 08:39
退会済みユーザー
2022/04/27 12:35