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); } } }