wpf 将多个 ObservableCollection 绑定到一个 ObservableCollection
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13203795/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Binding multiple ObservableCollections to One ObservableCollection
提问by Reza M.
Have a bunch of ObservableCollection<MeClass> Resultand require to combine them all into another ObservableCollection<MeClass> AllResultsso I can display it in a listview.
有一堆ObservableCollection<MeClass> Result并要求将它们全部组合成另一个,ObservableCollection<MeClass> AllResults以便我可以将它显示在listview.
Just not sure how to combine them all in one.
只是不确定如何将它们合二为一。
I Created a new class to combine them all but not sure how they will get updated after I got the list once... So not really sure which direction to take.
我创建了一个新类来将它们全部组合在一起,但不确定在我获得列表后它们将如何更新......所以不确定要采取哪个方向。
I know about INotifyPropertyChangedI'm just not sure how to combine them all and keep updating as everything changes.
我知道INotifyPropertyChanged我只是不确定如何将它们全部结合起来并随着一切变化而不断更新。
回答by Adi Lester
.NET has a CompositeCollectionthat allows you to treat multiple collections as a single collection. It implements INotifyCollectionChanged, so as long as your inner collections implement INotifyCollectionChangedas well (which in your case they certainly do), your bindings should work without any problems.
.NETCompositeCollection允许您将多个集合视为一个集合。它实现了INotifyCollectionChanged,所以只要您的内部集合也实现INotifyCollectionChanged了(在您的情况下它们肯定会实现),您的绑定应该可以正常工作。
Usage example:
用法示例:
CompositeCollection cc = new CompositeCollection();
CollectionContainer container1 = new CollectionContainer() { Collection = Result1 }
CollectionContainer container2 = new CollectionContainer() { Collection = Result2 }
cc.Add(container1);
cc.Add(container2);
回答by GazTheDestroyer
Something like this?
像这样的东西?
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;
}
}
}
回答by Drew Noakes
I reworked @GazTheDestroyer's answer into this (requires C# 7):
我将@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);
}
}
}

