2012-11-02 97 views
11

有一堆ObservableCollection<MeClass> Result並需要將它們全部合併爲另一個ObservableCollection<MeClass> AllResults,以便我可以將它顯示在listview中。將多個ObservableCollections綁定到一個ObservableCollection

只是不知道如何將它們合爲一體。

我創建了一個新的類來組合他們所有的人,但不知道他們將如何得到更新後,我得到了一次......所以不知道要採取哪個方向。

我知道關於INotifyPropertyChanged我只是不確定如何將它們全部結合起來,並隨着一切變化而不斷更新。

回答

21

.NET有一個CompositeCollection,它允許您將多個集合視爲一個集合。它實現INotifyCollectionChanged,所以只要你的內部集合實現INotifyCollectionChanged(在你的情況下它們當然可以),你的綁定應該沒有任何問題。

用例:

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

請注意,您不能使用「CompositeCollectionView」進行分組。它的'CanGroup'是'false',它的'ICollectionView.GroupDescriptions'屬性是'null'並且是不可設置的。 –

3

像這樣的東西?

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

無需推倒重來 - .NET將已經擁有CompositeCollection(見我的回答)。 –

+0

沒有碰到過!非常有用,謝謝! – GazTheDestroyer

+1

與框架的內置'CompositeCollection'不同,此方法適用於分組。謝謝。順便說一下'AddSubCollections'中的'All'符號是編譯錯誤。 –

0

我返工@ GazTheDestroyer的回答到這個(需要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); 
     } 
    } 
} 
相關問題