Maison >développement back-end >C++ >Comment notifier efficacement une collection observable des modifications au niveau des éléments ?

Comment notifier efficacement une collection observable des modifications au niveau des éléments ?

Linda Hamilton
Linda Hamiltonoriginal
2025-01-05 04:04:39267parcourir

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

Notifier ObservableCollection sur les modifications d'éléments

Dans les cas où des éléments d'une ObservableCollection subissent des modifications, il devient nécessaire de notifier la collection de ces modifications à assurer des mises à jour appropriées de l’interface utilisateur. Le comportement par défaut d'ObservableCollection ne parvient pas à observer les changements au niveau des éléments, ce qui incite à l'exploration de solutions alternatives.

TrulyObservableCollection

Une approche consiste à utiliser la classe TrulyObservableCollection, qui étend ObservableCollection et inclut un mécanisme d'abonnement pour les événements PropertyChanged sur ses éléments. Cela peut être implémenté comme suit :

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);
    }
}

Problèmes de mise en œuvre

Cependant, l'utilisation de TrulyObservableCollection peut ne pas donner les résultats souhaités. Pour exploiter pleinement ses capacités, la classe MyViewModel doit enregistrer un gestionnaire pour l'événement CollectionChanged de MyItemsSource :

public MyViewModel()
{
    MyItemsSource.CollectionChanged += MyItemsSource_CollectionChanged;
}

Approche alternative : Regular ObservableCollection

Une méthode alternative est pour utiliser un ObservableCollection standard et vous abonner manuellement aux événements PropertyChanged au niveau de l'élément dans CollectionChanged 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();
}

Avec cette approche, les mises à jour de l'interface utilisateur sont déclenchées spécifiquement lorsque la propriété MyProperty d'un élément change, éliminant ainsi le besoin de mises à jour grossières dans l'ensemble de la collection.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn