public static DisposableReadOnlyObservableCollection <TResult> MakeOneWayLinkedCollectionMany <TSource, TCollection, TResult>(this TCollection source, Func <TSource, IEnumerable <TResult> > selector) where TCollection : INotifyCollectionChanged, IEnumerable <TSource> { List <int> counts = new List <int>(); var ret = new DisposableObservableCollection <TResult>(source.Select(selector).SelectMany(x => { counts.Add(x?.Count() ?? 0); return(x ?? new TResult[0]); })); ret.AddDisposable(source.ObserveCollectionChanged <TCollection, TSource>((item, index) => { int idx = counts.Take(index).Sum(); int lastIdx = idx; foreach (var newItem in selector(item) ?? new TResult[0]) { ret.Insert(lastIdx++, newItem); } counts.Insert(index, lastIdx - idx); }, (item, index) => { int idx = counts.Take(index).Sum(); int lastIdx = idx + counts[index]; for (; idx < lastIdx; idx++) { ret.RemoveAt(idx); } counts.RemoveAt(index); }, () => { counts.Clear(); ret.Clear(); ret.AddRange(source.Select(selector).SelectMany(x => { counts.Add(x?.Count() ?? 0); return(x ?? new TResult[0]); })); })); return(new DisposableReadOnlyObservableCollection <TResult>(ret)); }
public static DisposableReadOnlyObservableCollection <TSource> ObservableConcat <TSource, TCollection>(this TCollection first, IEnumerable <TSource> second) where TCollection : INotifyCollectionChanged, IEnumerable <TSource> { var ret = new DisposableObservableCollection <TSource>(first.Concat(second)); ret.AddDisposable(first.ObserveCollectionChanged <TCollection, TSource>((item, index) => ret.Insert(index, item) , (item, index) => ret.RemoveAt(index) , () => { ret.Clear(); ret.AddRange(first.Concat(second)); })); return(new DisposableReadOnlyObservableCollection <TSource>(ret)); }
public static DisposableReadOnlyObservableCollection <TResult> MakeOneWayLinkedCollection <TSource, TCollection, TResult>(this TCollection source, Func <TSource, TResult> selector) where TCollection : INotifyCollectionChanged, IEnumerable <TSource> { var ret = new DisposableObservableCollection <TResult>(source.Select(selector)); ret.AddDisposable(source.ObserveCollectionChanged <TCollection, TSource>((item, index) => { ret.Insert(index, selector(item)); }, (item, index) => { ret.RemoveAt(index); }, () => { ret.Clear(); ret.AddRange(source.Select(selector)); })); return(new DisposableReadOnlyObservableCollection <TResult>(ret)); }