示例#1
0
        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);
            }
        }
示例#2
0
        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));
        }