ホームページ >バックエンド開発 >C++ >ObservableCollection に項目レベルの変更を効率的に通知するにはどうすればよいですか?

ObservableCollection に項目レベルの変更を効率的に通知するにはどうすればよいですか?

Linda Hamilton
Linda Hamiltonオリジナル
2025-01-05 04:04:39267ブラウズ

How to Efficiently Notify an ObservableCollection of Item-Level Changes?

項目の変更について 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 サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。