2012-11-02 12 views
11

Haben Sie eine Menge von ObservableCollection<MeClass> Result und müssen Sie alle in eine andere ObservableCollection<MeClass> AllResults kombinieren, damit ich sie in einer listview anzeigen kann.Mehrere ObservableCollections an eine ObservableCollection binden

Nur nicht sicher, wie man sie alle in einem kombiniert.

Ich habe eine neue Klasse erstellt, um sie alle zu kombinieren, aber nicht sicher, wie sie aktualisiert werden, nachdem ich die Liste einmal ... Also nicht wirklich sicher, welche Richtung zu nehmen.

Ich weiß über INotifyPropertyChanged Ich bin nur nicht sicher, wie man sie alle kombinieren und aktualisieren Sie, wie sich alles ändert.

Antwort

21

.NET hat eine CompositeCollection, dass Sie mehrere Sammlungen als eine einzige Sammlung behandeln können. Es implementiert INotifyCollectionChanged, so lange Ihre inneren Sammlungen auch INotifyCollectionChanged implementieren (was in Ihrem Fall sicherlich tun), sollten Ihre Bindungen ohne Probleme funktionieren.

Anwendungsbeispiel:

CompositeCollection cc = new CompositeCollection(); 
CollectionContainer container1 = new CollectionContainer() { Collection = Result1 } 
CollectionContainer container2 = new CollectionContainer() { Collection = Result2 } 
cc.Add(container1); 
cc.Add(container2); 
+2

Beachten Sie, dass Sie keine Gruppierung mit 'CompositeCollectionView' verwenden können. Es ist 'CanGroup' ist' false' und seine 'ICollectionView.GroupDescriptions' Eigenschaft ist' null' und kann nicht gesetzt werden. –

3

So ähnlich?

public class CompositeCollection : ObservableCollection<MeClass> 
{ 
    private ObservableCollection<MeClass> _subCollection1; 
    private ObservableCollection<MeClass> _subCollection2; 

    public CompositeCollection(ObservableCollection<MeClass> subCollection1, ObservableCollection<MeClass> subCollection2) 
    { 
     _subCollection1 = subCollection1; 
     _subCollection2 = subCollection2; 

     AddSubCollections(); 
     SubscribeToSubCollectionChanges(); 
    } 

    private void AddSubCollections() 
    { 
     AddItems(_subCollection1.All); 
     AddItems(_subCollection2.All); 
    } 

    private void AddItems(IEnumerable<MeClass> items) 
    { 
     foreach (MeClass me in items) 
      Add(me); 
    } 

    private void RemoveItems(IEnumerable<MeClass> items) 
    { 
     foreach (MeClass me in items) 
      Remove(me); 
    } 

    private void SubscribeToSubCollectionChanges() 
    { 
     _subCollection1.CollectionChanged += OnSubCollectionChanged; 
     _subCollection2.CollectionChanged += OnSubCollectionChanged; 
    } 

    private void OnSubCollectionChanged(object source, NotifyCollectionChangedEventArgs args) 
    { 
     switch(args.Action) 
     { 
      case NotifyCollectionChangedAction.Add: AddItems(args.NewItems.Cast<MeClass>()); 
                 break; 

      case NotifyCollectionChangedAction.Remove: RemoveItems(args.OldItems.Cast<MeClass>()); 
                 break; 

      case NotifyCollectionChangedAction.Reset: Clear(); 
                 AddSubCollections(); 
                 break; 
     } 
    } 
} 
+2

Keine Notwendigkeit, das Rad neu zu erfinden - .NET bereits ein Composite hat (siehe meine Antwort). –

+0

Hatte nicht auf das gestoßen! Sehr nützlich, danke! – GazTheDestroyer

+1

Dieser Ansatz funktioniert mit der Gruppierung, im Gegensatz zur integrierten CompositeCollection des Frameworks. Vielen Dank. Übrigens sind die Symbole 'Alle' in' AddSubCollections' Kompilierungsfehler. –

0

I @ in diese GazTheDestroyer Antwort überarbeitet (erfordert C# 7):

internal sealed class CompositeObservableCollection<T> : ObservableCollection<T> 
{ 
    public CompositeObservableCollection(INotifyCollectionChanged subCollection1, INotifyCollectionChanged subCollection2) 
    { 
     AddItems((IEnumerable<T>)subCollection1); 
     AddItems((IEnumerable<T>)subCollection2); 

     subCollection1.CollectionChanged += OnSubCollectionChanged; 
     subCollection2.CollectionChanged += OnSubCollectionChanged; 

     void OnSubCollectionChanged(object source, NotifyCollectionChangedEventArgs args) 
     { 
      switch (args.Action) 
      { 
       case NotifyCollectionChangedAction.Add: 
        AddItems(args.NewItems.Cast<T>()); 
        break; 
       case NotifyCollectionChangedAction.Remove: 
        RemoveItems(args.OldItems.Cast<T>()); 
        break; 
       case NotifyCollectionChangedAction.Reset: 
        Clear(); 
        AddItems((IEnumerable<T>)subCollection1); 
        AddItems((IEnumerable<T>)subCollection2); 
        break; 
       case NotifyCollectionChangedAction.Replace: 
        RemoveItems(args.OldItems.Cast<T>()); 
        AddItems(args.NewItems.Cast<T>()); 
        break; 
       case NotifyCollectionChangedAction.Move: 
        throw new NotImplementedException(); 
       default: 
        throw new ArgumentOutOfRangeException(); 
      } 
     } 

     void AddItems(IEnumerable<T> items) 
     { 
      foreach (var me in items) 
       Add(me); 
     } 

     void RemoveItems(IEnumerable<T> items) 
     { 
      foreach (var me in items) 
       Remove(me); 
     } 
    } 
}