Gabriel Mongeon

Official blog, et sûrement le seul...

Lecture de 2 Minutes

J’ai été confronté à une situation lors d’un développement d’une application WPF qui utilisait la classe ObservableCollection, voici la description:

Problème:

Collection d’items qui comporte plusieurs items (qui eux implémente l’interface INotifyPropertyChanged). Je dois faire certains calculs: Total des items à complétés, total des items complétés, items restants, etc. Mais lorsque qu’un de ces items changeait de statut et devenait complété, impossible de pousser l’information (push) à un niveau supérieur.

Solution proposée:

Utilisation d’un thread qui à chaque intervalle X, allez valider les totaux et mettre à jour les données sur l’interface, de façon tirer (pull). N’aimant pas vraiment cette idée et essayant de diminuer au minimum les pull pour privilégier les push, j’ai fait une petite recherche sur le sujet.

Solution implémentée:

J’ai trouvé la une solution sur StackOverflow, qui dérivait de ObservableCollection et implémentait l’interface INotifyPropertyChanged, soit la classe  ObservableCollectionEx<T>. Voici la classe en tant que telle:

public class ObservableCollectionEx : ObservableCollection where T : INotifyPropertyChanged 
  { 
    public ObservableCollectionEx() 
      : base() 
    { 
    } 
 
    protected override void OnCollectionChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e) 
    { 
      Unsubscribe(e.OldItems); 
      Subscribe(e.NewItems); 
      base.OnCollectionChanged(e); 
    } 
 
    private void Subscribe(System.Collections.IList iList) 
    { 
      if (iList != null) 
      { 
        foreach (T element in iList) 
          element.PropertyChanged += (x, y) => ContainedElementChanged(y); 
      } 
    } 
 
    private void Unsubscribe(System.Collections.IList iList) 
    { 
      if (iList != null) 
      { 
        foreach (T element in iList) 
          element.PropertyChanged -= (x, y) => ContainedElementChanged(y); 
      } 
    } 
 
    private void ContainedElementChanged(PropertyChangedEventArgs e) 
    { 
      OnPropertyChanged(e); 
    }
}

Très simple et surtout générique. Pour l’utilisation, soren.enemaerke (l’auteur original) propose ce petit bout de code:

ObservableCollectionEx collection = new ObservableCollectionEx(); 
((INotifyPropertyChanged)collection).PropertyChanged += (x,y) => ReactToChange();

Ce que je n’ai pas encore expérimenté, c’est d’étendre cette classe pour offrir un peu plus de fonctionnalités qui serait très utile, ce sera pour une prochaine fois.

Posts Récents