private void NotifySource(ICollectionChangedNotificationResult <TSource> sourceChange, List <TResult> added, List <TResult> removed) { if (sourceChange.RemovedItems != null) { foreach (var item in sourceChange.RemovedItems) { SubSourcePair wrapper; if (sourceItems.TryGetValue(item, out wrapper)) { removed.AddRange(wrapper); wrapper.Successors.Unset(this); sourceItems.Remove(item); } } } if (sourceChange.AddedItems != null) { foreach (var item in sourceChange.AddedItems) { var subSource = func.Observe(item); var wrapper = new SubSourcePair(subSource, item, this); wrapper.Successors.Set(this); sourceItems.Add(item, wrapper); added.AddRange(wrapper); } } }
protected override void OnAttach() { foreach (var item in source) { var subSource = func.Observe(item); var wrapper = new SubSourcePair(subSource, item, this); wrapper.Successors.Set(this); sourceItems.Add(item, wrapper); } }
private void NotifySource(CollectionChangedNotificationResult <TSource> sourceChange, List <TResult> added, List <TResult> removed) { if (sourceChange.RemovedItems != null) { foreach (var item in sourceChange.RemovedItems) { SubSourcePair wrapper; if (sourceItems.TryGetValue(item, out wrapper)) { removed.AddRange(wrapper); wrapper.Successors.Unset(this); sourceItems.Remove(item); } } } if (sourceChange.AddedItems != null) { foreach (var item in sourceChange.AddedItems) { var subSource = func.Observe(item); var wrapper = new SubSourcePair(subSource, item, this); wrapper.Successors.Set(this); sourceItems.Add(item, wrapper); added.AddRange(wrapper); } } if (sourceChange.ReplaceAddedItems != null) { for (int i = 0; i < sourceChange.ReplaceAddedItems.Count; i++) { var oldItem = sourceChange.ReplaceRemovedItems[i]; var newItem = sourceChange.ReplaceAddedItems[i]; var newSubSource = func.Observe(newItem); SubSourcePair wrapper; if (sourceItems.TryGetValue(oldItem, out wrapper)) { removed.AddRange(SL.Select(wrapper.Results.Values, res => res.Value)); wrapper.Successors.Unset(this); sourceItems.Remove(oldItem); } wrapper = new SubSourcePair(newSubSource, newItem, this); sourceItems.Add(newItem, wrapper); wrapper.Successors.Set(this); added.AddRange(SL.Select(wrapper.Results.Values, res => res.Value)); } } }
private static void AttachSubSource(SubSourcePair wrapper) { if (wrapper.SubSource.Value != null) { foreach (var element in wrapper.SubSource.Value) { wrapper.AttachResult(element); } var notifier = wrapper.SubSource.Value as INotifyCollectionChanged; if (notifier != null) { notifier.CollectionChanged += wrapper.OnCollectionChanged; } } }
protected override void AttachCore() { if (source != null) { foreach (var item in source) { var subSource = func.Observe(item); var wrapper = new SubSourcePair(subSource, item, this); sourceItems.Add(item, wrapper); AttachSubSource(wrapper); subSource.ValueChanged += wrapper.OnSourceChanged; } source.CollectionChanged += SourceCollectionChanged; } }
private void SourceCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { if (e.Action == NotifyCollectionChangedAction.Move) { return; } if (e.Action != NotifyCollectionChangedAction.Reset) { if (e.Action == NotifyCollectionChangedAction.Remove && e.OldItems != null) { var removed = new List <TResult>(); foreach (TSource item in e.OldItems) { SubSourcePair wrapper; if (sourceItems.TryGetValue(item, out wrapper)) { removed.AddRange(SL.Select(wrapper.Values.Values, res => res.Value)); DetachSubSource(item); } } OnRemoveItems(removed); } if (e.Action == NotifyCollectionChangedAction.Add && e.NewItems != null) { var added = new List <TResult>(); foreach (TSource item in e.NewItems) { var subSource = func.Observe(item); var wrapper = new SubSourcePair(subSource, item, this); sourceItems.Add(item, wrapper); AttachSubSource(wrapper); subSource.ValueChanged += wrapper.OnSourceChanged; added.AddRange(SL.Select(wrapper.Values.Values, res => res.Value)); } OnAddItems(added); } if (e.Action == NotifyCollectionChangedAction.Replace) { var removed = new List <TResult>(); var added = new List <TResult>(); for (int i = 0; i < e.OldItems.Count; i++) { var oldItem = (TSource)e.OldItems[i]; var newItem = (TSource)e.NewItems[i]; var newSubSource = func.Observe(newItem); SubSourcePair wrapper; if (sourceItems.TryGetValue(oldItem, out wrapper)) { if (wrapper.SubSource.Value != newSubSource.Value) { removed.AddRange(SL.Select(wrapper.Values.Values, res => res.Value)); DetachSubSource(oldItem); wrapper = new SubSourcePair(newSubSource, newItem, this); sourceItems.Add(newItem, wrapper); AttachSubSource(wrapper); newSubSource.ValueChanged += wrapper.OnSourceChanged; added.AddRange(SL.Select(wrapper.Values.Values, res => res.Value)); } else { wrapper.SubSource.ValueChanged -= wrapper.OnSourceChanged; wrapper.SubSource = newSubSource; wrapper.SubSource.ValueChanged += wrapper.OnSourceChanged; sourceItems.Remove(oldItem); sourceItems.Add(newItem, wrapper); wrapper.ReplaceItem(newItem); } } else { wrapper = new SubSourcePair(newSubSource, newItem, this); sourceItems.Add(newItem, wrapper); AttachSubSource(wrapper); newSubSource.ValueChanged += wrapper.OnSourceChanged; added.AddRange(SL.Select(wrapper.Values.Values, res => res.Value)); } } OnAddItems(added); OnRemoveItems(removed); } } else { DetachSource(); OnCleared(); } }