【问题标题】:Binding multiple ObservableCollections to One ObservableCollection将多个 ObservableCollection 绑定到一个 ObservableCollection
【发布时间】:2012-10-23 14:49:22
【问题描述】:

有一堆ObservableCollection<MeClass> Result,需要将它们全部组合成另一个ObservableCollection<MeClass> AllResults,这样我就可以在listview中显示它。

只是不知道如何将它们合二为一。

我创建了一个新类来组合它们,但不确定在获得列表后它们将如何更新......所以不太确定该采取哪个方向。

我知道INotifyPropertyChanged 我只是不确定如何将它们全部结合起来并随着一切的变化不断更新。

【问题讨论】:

    标签: c# .net wpf observablecollection inotifypropertychanged


    【解决方案1】:

    这样的?

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

    【讨论】:

    • 无需重新发明轮子 - .NET 已经有一个 CompositeCollection(见我的回答)。
    • 这种方法适用于分组,不像框架的内置CompositeCollection。谢谢。顺便说一句,AddSubCollections 中的 All 符号是编译错误。
    【解决方案2】:

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

    【讨论】:

    • 请注意,您不能使用CompositeCollectionView 进行分组。它的CanGroupfalse,它的ICollectionView.GroupDescriptions 属性是null 并且是不可设置的。
    【解决方案3】:

    我将@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);
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-04-10
      • 1970-01-01
      • 1970-01-01
      • 2013-09-07
      • 2019-02-24
      • 2011-05-20
      • 2013-03-03
      相关资源
      最近更新 更多