Example #1
0
        private void VirtualItemList_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            DataGridVirtualizingCollectionViewBase collectionView = this.GetCollectionView();

            lock (collectionView.DeferredOperationManager)
            {
                DeferredOperation deferredOperation = null;

                switch (e.Action)
                {
                case NotifyCollectionChangedAction.Replace:
                {
                    deferredOperation = new DeferredOperation(
                        DeferredOperation.DeferredOperationAction.Replace, -1,
                        e.NewStartingIndex + m_startGlobalIndex,
                        e.NewItems,
                        e.OldStartingIndex + m_startGlobalIndex,
                        e.OldItems);

                    break;
                }

                case NotifyCollectionChangedAction.Reset:
                {
                    deferredOperation = new DeferredOperation(
                        DeferredOperation.DeferredOperationAction.Refresh, -1, null);

                    break;
                }

                default:
                    throw new NotSupportedException(e.Action.ToString() + " is not a supported action.");
                }

                if (deferredOperation != null)
                {
                    collectionView.ExecuteOrQueueSourceItemOperation(deferredOperation);
                }
            }
        }
        internal override void ExecuteSourceItemOperation(DeferredOperation deferredOperation, out bool refreshForced)
        {
            refreshForced = false;

            switch (deferredOperation.Action)
            {
            case DeferredOperation.DeferredOperationAction.Add:
            case DeferredOperation.DeferredOperationAction.Move:
            case DeferredOperation.DeferredOperationAction.RefreshDistincValues:
            {
                Debug.Assert(false);
                break;
            }

            case DeferredOperation.DeferredOperationAction.Refresh:
            case DeferredOperation.DeferredOperationAction.Remove:
            case DeferredOperation.DeferredOperationAction.Resort:
            case DeferredOperation.DeferredOperationAction.Regroup:
            {
                this.ForceRefresh(true, false, true);
                break;
            }

            case DeferredOperation.DeferredOperationAction.Replace:
            {
                this.ReplaceSourceItem(deferredOperation.OldStartingIndex, deferredOperation.OldItems,
                                       deferredOperation.NewStartingIndex, deferredOperation.NewItems);
                break;
            }

            default:
            {
                base.ExecuteSourceItemOperation(deferredOperation, out refreshForced);
                break;
            }
            }
        }
        public bool ContainsItemForRemoveOperation(object item)
        {
            if (item == null)
            {
                throw new ArgumentNullException("item");
            }

            if (m_deferredOperations.Count == 0)
            {
                return(false);
            }

            int deferredOperationsCount = m_deferredOperations.Count;

            for (int i = 0; i < deferredOperationsCount; i++)
            {
                DeferredOperation deferredOperation = m_deferredOperations[i];

                if (deferredOperation.Action == DeferredOperation.DeferredOperationAction.Remove)
                {
                    int oldItemsCount = (deferredOperation.OldItems == null) ? 0 : deferredOperation.OldItems.Count;

                    for (int j = 0; j < oldItemsCount; j++)
                    {
                        object oldItem = deferredOperation.OldItems[j];

                        if (object.Equals(oldItem, item))
                        {
                            return(true);
                        }
                    }
                }
            }

            return(false);
        }
        public void Add(DeferredOperation operation)
        {
            lock (this)
            {
                if (this.RefreshPending)
                {
                    return;
                }

                switch (operation.Action)
                {
                case DeferredOperation.DeferredOperationAction.Refresh:
                {
                    this.RefreshPending = true;
                    m_deferredOperations.Clear();
                    break;
                }

                case DeferredOperation.DeferredOperationAction.RefreshDistincValues:
                {
                    if (operation.FilteredItemsChanged)
                    {
                        this.RefreshDistincValuesWithFilteredItemChangedPending = true;
                    }
                    else
                    {
                        this.RefreshDistincValuesPending = true;
                    }

                    break;
                }

                case DeferredOperation.DeferredOperationAction.Regroup:
                {
                    this.RegroupPending = true;
                    break;
                }

                case DeferredOperation.DeferredOperationAction.Resort:
                {
                    this.ResortPending = true;
                    break;
                }

                default:
                {
                    m_deferredOperations.Add(operation);
                    m_hasNewOperationsSinceStartTime = true;

                    if (this.DeferProcessOfInvalidatedGroupStats)
                    {
                        m_deferredOperationsToProcess++;
                    }

                    break;
                }
                }

                if ((m_dispatcher != null) && (m_dispatcherOperation == null))
                {
                    Debug.Assert(m_collectionView.Loaded);

                    m_dispatcherOperation            = m_dispatcher.BeginInvoke(DispatcherPriority.DataBind, new DispatcherOperationCallback(this.Dispatched_Process), null);
                    m_dispatcherOperationStartTime   = DateTime.UtcNow;
                    m_hasNewOperationsSinceStartTime = false;
                }
            }
        }
        public void PurgeAddWithRemoveOrReplace()
        {
            if (m_deferredOperations.Count >= 2)
            {
                DeferredOperation addOperation = m_deferredOperations[0];

                if (addOperation.Action != DeferredOperation.DeferredOperationAction.Add)
                {
                    return;
                }

                int addIndex = addOperation.NewStartingIndex;
                int addCount = addOperation.NewItems.Count;

                int firstIndexToRemove = 1;
                int lastIndexToRemove  = -1;

                int count = m_deferredOperations.Count;
                for (int i = 1; i < count; i++)
                {
                    DeferredOperation operation = m_deferredOperations[i];

                    bool replaced = (operation.Action == DeferredOperation.DeferredOperationAction.Replace);
                    bool removed  = (operation.Action == DeferredOperation.DeferredOperationAction.Remove);

                    if (replaced || removed)
                    {
                        if (removed && (i < count - 1))
                        {
                            Debug.Fail("How come we have a remove operation before the end?");
                            return;
                        }

                        if ((addIndex == operation.OldStartingIndex) &&
                            (addCount == operation.OldItems.Count))
                        {
                            lastIndexToRemove = i;

                            if (removed)
                            {
                                firstIndexToRemove = 0;
                            }
                        }
                        else
                        {
                            Debug.Fail("Why do we have a replace or remove operation with different indexes?");
                            return;
                        }
                    }
                    else
                    {
                        // Can be normal, we can receive 2 add for the same item and same position
                        // when we are bound to an IBindingList ( like a DataView )
                        return;
                    }
                }

                if (lastIndexToRemove > -1)
                {
                    m_deferredOperations.RemoveRange(firstIndexToRemove, (lastIndexToRemove - firstIndexToRemove) + 1);
                }
            }
        }