Связывание нескольких ObservableCollections с одним ObservableCollection
Имейте кучу ObservableCollection<MeClass> Result
и требуйте объединить их все в другой ObservableCollection<MeClass> AllResults
, чтобы я мог отображать его в listview
.
Просто не уверен, как объединить их все в одном.
Я создал новый класс, чтобы объединить их все, но не уверен, как они будут обновляться после того, как я получу список один раз... Так что не совсем уверен, в каком направлении двигаться.
Я знаю о INotifyPropertyChanged
Я просто не уверен, как объединить их все и продолжать обновлять, поскольку все изменяется.
Ответы
Ответ 1
.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
Что-то вроде этого?
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;
}
}
}
Ответ 3
Я переработал @GazTheDestroyer ответ на это (требуется С# 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);
}
}
}