void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { Action action; if (_list == null) { action = Clear; } else { action = () => { _version++; OnCollectionChanged(e); }; } CollectionSynchronizationContext sync; if (BindingBase.TryGetSynchronizedCollection(ProxiedEnumerable, out sync)) { sync.Callback(ProxiedEnumerable, sync.Context, () => { e = e.WithCount(Count); _dispatcher.Dispatch(action); }, false); } else { e = e.WithCount(Count); _dispatcher.Dispatch(action); } }
bool TryGetValue(int index, out object value) { value = null; CollectionSynchronizationContext syncContext; BindingBase.TryGetSynchronizedCollection(ProxiedEnumerable, out syncContext); if (_list != null) { object indexedValue = null; var inRange = false; Action getFromList = () => { if (index >= _list.Count) { return; } indexedValue = _list[index]; inRange = true; }; if (syncContext != null) { syncContext.Callback(ProxiedEnumerable, syncContext.Context, getFromList, false); } else { getFromList(); } value = indexedValue; return(inRange); } if (_collection != null && index >= _collection.Count) { return(false); } if (_items != null) { bool found = _items.TryGetValue(index, out value); if (found || _finished) { return(found); } } if (index >= _windowIndex + _windowSize) { int newIndex = index - _windowSize / 2; ClearRange(_windowIndex, newIndex - _windowIndex); _windowIndex = newIndex; } else if (index < _windowIndex) { int clearIndex = _windowIndex; int clearSize = _windowSize; if (clearIndex <= index + clearSize) { int diff = index + clearSize - clearIndex; clearIndex += diff + 1; clearSize -= diff; } ClearRange(clearIndex, clearSize); _windowIndex = 0; var dispose = _enumerator as IDisposable; if (dispose != null) { dispose.Dispose(); } _enumerator = null; _enumeratorIndex = 0; } if (_enumerator == null) { _enumerator = ProxiedEnumerable.GetEnumerator(); } if (_items == null) { _items = new Dictionary <int, object>(); } var countChanged = false; int end = _windowIndex + _windowSize; for (; _enumeratorIndex < end; _enumeratorIndex++) { var moved = false; Action move = () => { try { moved = _enumerator.MoveNext(); } catch (InvalidOperationException ioex) { throw new InvalidOperationException("You must call UpdateNonNotifyingList() after updating a list that does not implement INotifyCollectionChanged", ioex); } if (!moved) { var dispose = _enumerator as IDisposable; if (dispose != null) { dispose.Dispose(); } _enumerator = null; _enumeratorIndex = 0; _finished = true; } }; if (syncContext == null) { move(); } else { syncContext.Callback(ProxiedEnumerable, syncContext.Context, move, false); } if (!moved) { break; } if (CountIndex(_enumeratorIndex)) { countChanged = true; } if (_enumeratorIndex >= _windowIndex) { _items.Add(_enumeratorIndex, _enumerator.Current); } } if (countChanged) { OnCountChanged(); } return(_items.TryGetValue(index, out value)); }