using System.Collections.Generic; using System.Collections.ObjectModel; using System.Collections.Specialized; using System.ComponentModel; using System.Threading; namespace Developpez.Dotnet.Windows.Collections { /// /// Représente une collection de données dynamiques qui fournit des notifications lorsque des éléments sont ajoutés, /// supprimés ou lorsque la liste entière est actualisée. Les évènements sont toujours levés sur le thread qui a créé /// la collection, de façon à permettre le binding sur la collection même lorsqu'elle est modifiée de façon asynchrone. /// /// Le type des éléments de la collection public class AsyncObservableCollection : ObservableCollection { private SynchronizationContext _synchronizationContext = SynchronizationContext.Current; /// /// Initialise une nouvelle instance de la classe AsyncObservableCollection<T>. /// public AsyncObservableCollection() { } /// /// Initialise une nouvelle instance de la classe AsyncObservableCollection<T> qui contient des éléments copiés depuis la collection spécifiée. /// /// Collection à partir de laquelle les éléments sont copiés. public AsyncObservableCollection(IEnumerable list) : base(list) { } /// /// Déclenche l'événement CollectionChanged avec les arguments fournis. Si cette méthode est appelée à partir du thread qui a créé la collection, /// les gestionnaires abonnés à l'évènement sont appelés directement. Sinon, ils sont invoqués sur le thread qui a créé la collection. /// /// Arguments de l'événement déclenché. protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e) { if (SynchronizationContext.Current == _synchronizationContext) { // On déclenche l'évènement CollectionChanged sur le thread courant base.OnCollectionChanged(e); } else { // On déclenche l'évènement CollectionChanged sur le thread qui a créé la collection _synchronizationContext.Send(RaiseCollectionChanged, e); } } private void RaiseCollectionChanged(object param) { base.OnCollectionChanged((NotifyCollectionChangedEventArgs)param); } /// /// Déclenche l'événement PropertyChanged avec les arguments fournis. Si cette méthode est appelée à partir du thread qui a créé la collection, /// les gestionnaires abonnés à l'évènement sont appelés directement. Sinon, ils sont invoqués sur le thread qui a créé la collection. /// /// Arguments de l'événement déclenché. protected override void OnPropertyChanged(PropertyChangedEventArgs e) { if (SynchronizationContext.Current == _synchronizationContext) { // On déclenche l'évènement PropertyChanged sur le thread courant base.OnPropertyChanged(e); } else { // On déclenche l'évènement PropertyChanged sur le thread qui a créé la collection _synchronizationContext.Send(RaisePropertyChanged, e); } } private void RaisePropertyChanged(object param) { base.OnPropertyChanged((PropertyChangedEventArgs)param); } } }