項目の変更について ObservableCollection に通知する
ObservableCollection 内の項目が変更される場合、これらの変更をコレクションに通知する必要があります。 UI が適切に更新されていることを確認します。 ObservableCollection のデフォルトの動作では項目レベルの変更を監視するには不十分であるため、代替ソリューションの検討が必要です。
TrulyObservableCollection
1 つのアプローチには、TrulyObservableCollection クラスを利用することが含まれます。 ObservableCollection には、そのアイテムの PropertyChanged イベントのサブスクリプション メカニズムが含まれています。これは次のように実装できます。
public class TrulyObservableCollection<T> : ObservableCollection<T> where T : INotifyPropertyChanged { public TrulyObservableCollection() : base() { CollectionChanged += TrulyObservableCollection_CollectionChanged; } void TrulyObservableCollection_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { if (e.NewItems != null) { foreach (Object item in e.NewItems) { (item as INotifyPropertyChanged).PropertyChanged += new PropertyChangedEventHandler(item_PropertyChanged); } } if (e.OldItems != null) { foreach (Object item in e.OldItems) { (item as INotifyPropertyChanged).PropertyChanged -= new PropertyChangedEventHandler(item_PropertyChanged); } } } void item_PropertyChanged(object sender, PropertyChangedEventArgs e) { NotifyCollectionChangedEventArgs a = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset); OnCollectionChanged(a); } }
実装の問題
ただし、TrulyObservableCollection を使用すると、望ましい結果が得られない可能性があります。その機能を最大限に活用するには、MyViewModel クラスで MyItemsSource の CollectionChanged イベントのハンドラーを登録する必要があります。
public MyViewModel() { MyItemsSource.CollectionChanged += MyItemsSource_CollectionChanged; }
代替アプローチ: 通常の ObservableCollection
代替メソッドは次のとおりです。標準の ObservableCollection を採用し、CollectionChanged 内の項目レベルの PropertyChanged イベントを手動でサブスクライブします。 handler:
public MyViewModel() { MyItemsSource.CollectionChanged += MyItemsSource_CollectionChanged; // Add items to the collection MyItemsSource.Add(new MyType() { MyProperty = false }); MyItemsSource.Add(new MyType() { MyProperty = true}); MyItemsSource.Add(new MyType() { MyProperty = false }); } void MyItemsSource_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { if (e.NewItems != null) foreach(MyType item in e.NewItems) item.PropertyChanged += MyType_PropertyChanged; if (e.OldItems != null) foreach(MyType item in e.OldItems) item.PropertyChanged -= MyType_PropertyChanged; } void MyType_PropertyChanged(object sender, PropertyChangedEventArgs e) { if (e.PropertyName == "MyProperty") DoWork(); }
このアプローチでは、アイテムの MyProperty が変更されたときに UI の更新が特にトリガーされるため、コレクション全体にわたる大まかな更新の必要がなくなります。
以上がObservableCollection に項目レベルの変更を効率的に通知するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。