/// <inheritdoc/>
        public override void Enqueue(T item)
        {
            var count    = this.Count;
            var overflow = default(T);

            if (this.Count >= this.Size)
            {
                while (this.Count >= this.Size && this.TryDequeue(out overflow))
                {
                }
            }

            base.Enqueue(item);
            if (this.Count != count)
            {
                this.OnPropertyChanged(CachedEventArgs.CountPropertyChanged);
            }

            if (count >= this.Size)
            {
                this.OnCollectionChanged(Diff.CreateRemoveEventArgs(overflow, 0));
            }

            this.OnCollectionChanged(Diff.CreateAddEventArgs(item, this.Count - 1));
        }
예제 #2
0
        public override void Enqueue(T item)
        {
            var count    = this.Count;
            T   overflow = default(T);

            if (this.Count >= this.Size)
            {
                while (this.Count >= this.Size && this.TryDequeue(out overflow))
                {
                }
            }

            base.Enqueue(item);
            if (this.Count != count)
            {
                this.OnPropertyChanged(Notifier.CountPropertyChangedEventArgs);
            }

            this.OnPropertyChanged(Notifier.IndexerPropertyChangedEventArgs);
            if (count >= this.Size)
            {
                this.CollectionChanged.Notify(this, Diff.CreateRemoveEventArgs(overflow, 0), this.scheduler);
            }

            this.CollectionChanged.Notify(this, Diff.CreateAddEventArgs(item, this.Count - 1), this.scheduler);
        }
        void IList.Remove(object value)
        {
            var index = this.IndexOf((T)value);

            if (index < 0)
            {
                return;
            }

            this.isUpdatingSourceItem = value;
            this.RemoveAtCore(index);
            this.RefreshNow(Diff.CreateRemoveEventArgs(value, index));
            this.isUpdatingSourceItem = null;
        }
예제 #4
0
        private void Update(Chunk <NotifyCollectionChangedEventArgs> changes)
        {
            if (changes == null || changes.Count == 0)
            {
                return;
            }

            using (changes.ClearTransaction())
            {
                if (changes.Count > 1)
                {
                    this.Refresh(changes);
                    return;
                }

                var e = changes[0];
                switch (e.Action)
                {
                case NotifyCollectionChangedAction.Add:
                {
                    if (!e.TryGetSingleNewItem(out TSource newSource))
                    {
                        goto case NotifyCollectionChangedAction.Reset;
                    }

                    var index = e.NewStartingIndex;
                    var value = this.GetOrCreate(newSource, index);
                    this.Tracker.Insert(index, value);
                    var args = this.UpdateRange(index + 1, this.Count - 1);
                    args.Add(Diff.CreateAddEventArgs(value, index));
                    this.Notify(args);
                    break;
                }

                case NotifyCollectionChangedAction.Remove:
                {
                    if (!e.TryGetSingleOldItem(out TSource oldSource))
                    {
                        goto case NotifyCollectionChangedAction.Reset;
                    }

                    var index = e.OldStartingIndex;
                    var value = this.Tracker[index];
                    this.Tracker.RemoveAt(index);
                    var argses = this.UpdateRange(index, this.Count - 1);
                    argses.Add(Diff.CreateRemoveEventArgs(value, index));
                    this.Notify(argses);
                    this.factory.Remove(oldSource, value);
                    break;
                }

                case NotifyCollectionChangedAction.Replace:
                {
                    if (!e.TryGetSingleNewItem(out TSource newSource) ||
                        !e.TryGetSingleOldItem(out TSource oldSource))
                    {
                        goto case NotifyCollectionChangedAction.Reset;
                    }

                    var index    = e.NewStartingIndex;
                    var value    = this.GetOrCreate(newSource, index);
                    var oldValue = this.Tracker[e.OldStartingIndex];
                    this.Tracker[index] = value;
                    var arg = Diff.CreateReplaceEventArgs(value, oldValue, index);
                    this.Notify(arg);
                    this.factory.Remove(oldSource, oldValue);
                    break;
                }

                case NotifyCollectionChangedAction.Move:
                {
                    var value = this.Tracker[e.OldStartingIndex];
                    this.Tracker.RemoveAt(e.OldStartingIndex);
                    this.Tracker.Insert(e.NewStartingIndex, value);
                    var args = this.UpdateRange(Math.Min(e.OldStartingIndex, e.NewStartingIndex), Math.Max(e.OldStartingIndex, e.NewStartingIndex));
                    args.Add(Diff.CreateMoveEventArgs(value, e.NewStartingIndex, e.OldStartingIndex));
                    this.Notify(args);
                    break;
                }

                case NotifyCollectionChangedAction.Reset:
                    using (this.factory.RefreshTransaction())
                    {
                        this.Refresh(changes);
                    }

                    break;

                default:
                    throw new ArgumentOutOfRangeException(nameof(changes));
                }
            }
        }
예제 #5
0
        protected virtual void OnSourceCollectionChanged(IReadOnlyList <NotifyCollectionChangedEventArgs> changeCollection)
        {
            if (changeCollection == null || changeCollection.Count == 0)
            {
                return;
            }

            if (changeCollection.Count > 1)
            {
                this.Refresh();
                return;
            }

            var singleChange = changeCollection[0];

            try
            {
                switch (singleChange.Action)
                {
                case NotifyCollectionChangedAction.Add:
                {
                    var index = singleChange.NewStartingIndex;
                    var value = this.GetOrCreateValue(this.source.ElementAt(index), index);
                    this.mapped.Insert(index, value);
                    var changes = this.UpdateIndicesFrom(index + 1);
                    var change  = Diff.CreateAddEventArgs(value, index);
                    changes.Add(change);
                    base.Refresh(changes);
                    break;
                }

                case NotifyCollectionChangedAction.Remove:
                {
                    var index = singleChange.OldStartingIndex;
                    var value = this.mapped[index];
                    this.mapped.RemoveAt(index);
                    var changes = this.UpdateIndicesFrom(index);
                    var change  = Diff.CreateRemoveEventArgs(value, index);
                    changes.Add(change);
                    base.Refresh(changes);
                    break;
                }

                case NotifyCollectionChangedAction.Replace:
                {
                    var index    = singleChange.NewStartingIndex;
                    var value    = this.GetOrCreateValue(this.source.ElementAt(index), index);
                    var oldValue = this.mapped[singleChange.OldStartingIndex];
                    this.mapped[index] = value;
                    var change = Diff.CreateReplaceEventArgs(value, oldValue, index);
                    base.Refresh(new[] { change });
                    break;
                }

                case NotifyCollectionChangedAction.Move:
                {
                    var value = this.mapped[singleChange.OldStartingIndex];
                    this.mapped.RemoveAt(singleChange.OldStartingIndex);
                    this.mapped.Insert(singleChange.NewStartingIndex, value);
                    this.UpdateIndex(singleChange.OldStartingIndex);
                    this.UpdateIndex(singleChange.NewStartingIndex);
                    var change = Diff.CreateMoveEventArgs(this.mapped[singleChange.NewStartingIndex], singleChange.NewStartingIndex, singleChange.OldStartingIndex);
                    base.Refresh(new[] { change });
                    break;
                }

                case NotifyCollectionChangedAction.Reset:
                    this.Refresh();
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }
            catch (Exception)
            {
                this.Refresh(); // Resetting
            }
        }