void IListenCollectionChanged.CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { switch (e.Action) { case NotifyCollectionChangedAction.Add: for (int i = 0; i < e.NewItems.Count; i++) { Items.InsertImpl(e.NewStartingIndex + i, e.NewItems[i]); } break; case NotifyCollectionChangedAction.Remove: for (int i = 0; i < e.OldItems.Count; i++) { Items.RemoveAtImpl(e.OldStartingIndex); } break; case NotifyCollectionChangedAction.Replace: for (int i = 0; i < e.NewItems.Count; i++) { Items.SetItemImpl(e.NewStartingIndex + i, e.NewItems[i]); } break; case NotifyCollectionChangedAction.Reset: Items.ClearImpl(); foreach (var v in ItemsSource) { Items.AddImpl(v); } break; } OnItemsChanged(e); }
internal virtual void OnItemsSourceChanged(IEnumerable oldSource, IEnumerable newSource) { if (CollectionListener != null) { CollectionListener.Detach(); CollectionListener = null; } if (newSource != null) { if (newSource is INotifyCollectionChanged) { CollectionListener = new WeakCollectionChangedListener(((INotifyCollectionChanged)newSource), this); } Items.SetIsReadOnly(true); itemsIsDataBound = true; Items.ClearImpl(); foreach (var v in newSource) { Items.AddImpl(v); } // Setting itemsIsDataBound to true prevents normal notifications from propagating, so do it manually here OnItemsChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); } else { itemsIsDataBound = false; Items.SetIsReadOnly(false); Items.ClearImpl(); } // Yes this is stupid and shouldn't be here, but DRT 348 sets an empty collection as the ItemsSource // and expects the LayoutUpdated event to be raised. This is the only way that makes sense for this // to happen. It's all very strange. InvalidateMeasure(); }