private void OnVirtualItemListCollectionChanged(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 virtual void Remove( object item ) { if( !this.CanRemove ) throw new InvalidOperationException( "An attempt was made to remove an item from a source that does not support removal." ); if( this.IsEditingItem || this.IsAddingNew ) throw new InvalidOperationException( "An attempt was made to remove an item while an item is being edited or added." ); int sourceIndex = -2; if( ( !this.HasSource ) || ( !this.IsSourceSupportingChangeNotification ) ) sourceIndex = this.IndexOfSourceItem( item ); DataGridRemovingItemEventArgs removingItemEventArgs = new DataGridRemovingItemEventArgs( this, item, -1, false ); this.RootDataGridCollectionViewBase.OnRemovingItem( removingItemEventArgs ); if( removingItemEventArgs.Cancel ) throw new DataGridException( "Remove was canceled." ); if( !removingItemEventArgs.Handled ) { if( !this.HasSource ) throw new InvalidOperationException( "The RemovingItem event must be handled when not using an underlying data source." ); if( sourceIndex == -2 ) sourceIndex = this.IndexOfSourceItem( item ); if( sourceIndex != -1 ) this.InternalRemoveAt( sourceIndex ); } if( ( !this.HasSource ) || ( !this.IsSourceSupportingChangeNotification ) ) { DeferredOperation deferredOperation = new DeferredOperation( DeferredOperation.DeferredOperationAction.Remove, sourceIndex, new object[] { item } ); this.ExecuteOrQueueSourceItemOperation( deferredOperation ); } DataGridItemRemovedEventArgs itemRemovedEventArgs = new DataGridItemRemovedEventArgs( this, item, -1 ); this.RootDataGridCollectionViewBase.OnItemRemoved( itemRemovedEventArgs ); }
public virtual void CommitNew() { if( m_currentAddItem == null ) return; object item = m_currentAddItem; DeferredOperation addOperationToNotifyIfNotAlreadyQueued = null; this.QueueOperationForAddNew = true; try { DataGridCommittingNewItemEventArgs committingNewItemEventArgs = new DataGridCommittingNewItemEventArgs( this, m_currentAddItem, false ); this.RootDataGridCollectionViewBase.OnCommittingNewItem( committingNewItemEventArgs ); if( committingNewItemEventArgs.Cancel ) throw new DataGridException( "CommitNew was canceled." ); if( this.CreatingNewItemIsManuallyHandled != committingNewItemEventArgs.Handled ) throw new InvalidOperationException( "When manually handling the item-insertion process the CreatingNewItem, CommittingNewItem, and CancelingNewItem events must all be handled." ); if( !committingNewItemEventArgs.Handled ) { if( !this.HasSource ) throw new InvalidOperationException( "The CommittingNewItem event must be handled when not using an underlying data source." ); int addItemPosition = m_currentAddItemPosition; ItemsSourceHelper.EndNewDataItem( this.Enumeration, null, m_currentAddItem, ref addItemPosition ); addOperationToNotifyIfNotAlreadyQueued = new DeferredOperation( DeferredOperation.DeferredOperationAction.Add, addItemPosition + 1, addItemPosition, new object[] { m_currentAddItem } ); } else { if( committingNewItemEventArgs.Index == -1 ) throw new InvalidOperationException( "An attempt was made to handle the CommittingNewItem event without providing the index at which the new item was inserted." ); if( committingNewItemEventArgs.NewCount == -1 ) throw new InvalidOperationException( "An attempt was made to handle the CommittingNewItem event without providing the new item count." ); if( committingNewItemEventArgs.Index >= committingNewItemEventArgs.NewCount ) throw new InvalidOperationException( "The index at which the new item was inserted was greater than the new item count." ); addOperationToNotifyIfNotAlreadyQueued = new DeferredOperation( DeferredOperation.DeferredOperationAction.Add, committingNewItemEventArgs.NewCount, committingNewItemEventArgs.Index, new object[] { m_currentAddItem } ); } this.SetCurrentAddNew( null, -1 ); } finally { this.QueueOperationForAddNew = false; } if( m_deferredAddNewOperationManager != null ) { m_deferredAddNewOperationManager.PurgeAddWithRemoveOrReplace(); DeferredOperationManager deferredOperationManager = this.DeferredOperationManager; lock( deferredOperationManager ) { if( this.ShouldDeferOperation ) { deferredOperationManager.Combine( m_deferredAddNewOperationManager ); } else { m_deferredAddNewOperationManager.Process(); } } m_deferredAddNewOperationManager = null; } else { Debug.Assert( !this.IsSourceSupportingChangeNotification ); // No pending operation was in m_deferredAddNewOperationManager, // so the list have not trigger notification for the new item added. // We will, in that case, raise the notification ourself. this.ExecuteOrQueueSourceItemOperation( addOperationToNotifyIfNotAlreadyQueued ); } DataGridItemEventArgs itemEventArgs = new DataGridItemEventArgs( this, item ); m_rootDataGridCollectionViewBase.OnNewItemCommitted( itemEventArgs ); }
private void AddDeferredOperationForAddNew( DeferredOperation deferredOperation ) { if( m_deferredAddNewOperationManager == null ) m_deferredAddNewOperationManager = new DeferredOperationManager( this, null, false ); m_deferredAddNewOperationManager.Add( deferredOperation ); }
internal void AddDeferredOperation( DeferredOperation deferredOperation ) { m_deferredOperationManager.Add( deferredOperation ); }
internal virtual void ExecuteSourceItemOperation( DeferredOperation deferredOperation, out bool refreshForced ) { throw new NotSupportedException( deferredOperation.Action.ToString() + " is not a supported action." ); }
internal void ExecuteOrQueueSourceItemOperation( DeferredOperation deferredOperation ) { bool queueOperationForPendingAddNew = this.MustQueueOperationForPendingAddNew( deferredOperation.OldStartingIndex, deferredOperation.OldItems, deferredOperation.NewItems ); if( ( this.ShouldDeferOperation ) || ( queueOperationForPendingAddNew ) ) { if( queueOperationForPendingAddNew ) { this.AddDeferredOperationForAddNew( deferredOperation ); } else { this.AddDeferredOperation( deferredOperation ); } } else { bool refreshForced; this.ExecuteSourceItemOperation( deferredOperation, out refreshForced ); } }
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 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); } } }
public void Add(DeferredOperation operation) { lock (this) { if (this.RefreshPending) { return; } switch (operation.Action) { case DeferredOperation.DeferredOperationAction.Refresh: { this.RefreshPending = true; m_deferredOperations = null; 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: { if (m_deferredOperations == null) { m_deferredOperations = new List <DeferredOperation>(); } m_deferredOperations.Add(operation); break; } } if ((m_dispatcher != null) && (m_dispatcherOperation == null)) { Debug.Assert(m_collectionViewToUpdate.Loaded); m_dispatcherOperation = m_dispatcher.BeginInvoke( DispatcherPriority.DataBind, new DispatcherOperationCallback(this.Dispatched_Process), null); } } }
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 void Add( DeferredOperation operation ) { lock( this ) { if( this.RefreshPending ) return; switch( operation.Action ) { case DeferredOperation.DeferredOperationAction.Refresh: { this.RefreshPending = true; m_deferredOperations = null; 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: { if( m_deferredOperations == null ) m_deferredOperations = new List<DeferredOperation>(); m_deferredOperations.Add( operation ); break; } } if( ( m_dispatcher != null ) && ( m_dispatcherOperation == null ) ) { Debug.Assert( m_collectionViewToUpdate.Loaded ); m_dispatcherOperation = m_dispatcher.BeginInvoke( DispatcherPriority.DataBind, new DispatcherOperationCallback( this.Dispatched_Process ), null ); } } }
private void NotifyCollectionChanged_CollectionChanged( object sender, NotifyCollectionChangedEventArgs e ) { Debug.Assert( !( this is DataGridVirtualizingCollectionViewBase ), "The DataGridVirtualizingCollectionView is unbound and therefore should never receive a notification from a source." ); lock( m_deferredOperationManager ) { if( m_deferredOperationManager.RefreshPending ) return; DeferredOperation deferredOperation = null; switch( e.Action ) { case NotifyCollectionChangedAction.Add: { CollectionView collectionView = m_enumeration as CollectionView; int count = ( collectionView == null ) ? -1 : collectionView.Count; deferredOperation = new DeferredOperation( DeferredOperation.DeferredOperationAction.Add, count, e.NewStartingIndex, e.NewItems ); break; } case NotifyCollectionChangedAction.Move: { deferredOperation = new DeferredOperation( DeferredOperation.DeferredOperationAction.Move, -1, e.NewStartingIndex, e.NewItems, e.OldStartingIndex, e.OldItems ); break; } case NotifyCollectionChangedAction.Remove: { deferredOperation = new DeferredOperation( DeferredOperation.DeferredOperationAction.Remove, e.OldStartingIndex, e.OldItems ); break; } case NotifyCollectionChangedAction.Replace: { deferredOperation = new DeferredOperation( DeferredOperation.DeferredOperationAction.Replace, -1, e.NewStartingIndex, e.NewItems, e.OldStartingIndex, 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 ) this.ExecuteOrQueueSourceItemOperation( deferredOperation ); } }
private void BindingList_ListChanged( object sender, ListChangedEventArgs e ) { Debug.Assert( !( this is DataGridVirtualizingCollectionViewBase ), "The DataGridVirtualizingCollectionView is unbound and therefore should never receive a notification from a source." ); IBindingList bindingList = ( IBindingList )m_enumeration; int index = e.NewIndex; IList items = null; ListChangedType listChangedType = e.ListChangedType; //If we're within bounds if( ( index > -1 ) && ( index < bindingList.Count ) ) { //Let's get the item items = new object[] { bindingList[ index ] }; } else { //Let's reset the list because a change to the list has happenned (e.g. a delete) before we had a chance to process the current change. listChangedType = ListChangedType.Reset; } lock( m_deferredOperationManager ) { if( m_deferredOperationManager.RefreshPending ) return; DeferredOperation deferredOperation = null; switch( listChangedType ) { case ListChangedType.ItemAdded: { deferredOperation = new DeferredOperation( DeferredOperation.DeferredOperationAction.Add, bindingList.Count, index, items ); break; } case ListChangedType.ItemChanged: { DataGridCollectionView view = this as DataGridCollectionView; if( view != null && view.UpdateChangedPropertyStatsOnly && e.PropertyDescriptor != null ) { view.CalculateChangedPropertyStatsOnly = true; foreach( Stats.StatFunction statFunc in view.StatFunctions ) { if( statFunc.SourcePropertyName.Contains( e.PropertyDescriptor.Name ) && !view.InvalidatedStatFunctions.Contains( statFunc ) ) { view.InvalidatedStatFunctions.Add( statFunc ); } } } deferredOperation = new DeferredOperation( DeferredOperation.DeferredOperationAction.Replace, -1, index, items, index, items ); break; } case ListChangedType.ItemDeleted: { deferredOperation = new DeferredOperation( DeferredOperation.DeferredOperationAction.Remove, index, new object[ 1 ] ); break; } case ListChangedType.ItemMoved: { deferredOperation = new DeferredOperation( DeferredOperation.DeferredOperationAction.Move, -1, index, items, e.OldIndex, items ); break; } case ListChangedType.Reset: { deferredOperation = new DeferredOperation( DeferredOperation.DeferredOperationAction.Refresh, -1, null ); break; } case ListChangedType.PropertyDescriptorAdded: { if( this.CheckAccess() ) { this.HandlePropertyDescriptorAdded( e.PropertyDescriptor ); } else { this.Dispatcher.Invoke( new Action<PropertyDescriptor>( this.HandlePropertyDescriptorAdded ), e.PropertyDescriptor ); } break; } case ListChangedType.PropertyDescriptorChanged: { if( this.CheckAccess() ) { this.HandlePropertyDescriptorChanged( e.PropertyDescriptor ); } else { this.Dispatcher.Invoke( new Action<PropertyDescriptor>( this.HandlePropertyDescriptorChanged ), e.PropertyDescriptor ); } break; } case ListChangedType.PropertyDescriptorDeleted: { if( this.CheckAccess() ) { this.HandlePropertyDescriptorDeleted( e.PropertyDescriptor ); } else { this.Dispatcher.Invoke( new Action<PropertyDescriptor>( this.HandlePropertyDescriptorDeleted ), e.PropertyDescriptor ); } break; } default: throw new NotSupportedException( "This ListChangedType (" + listChangedType.ToString() + ") is not supported." ); } if( deferredOperation != null ) { this.ExecuteOrQueueSourceItemOperation( deferredOperation ); } } }
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 ); } }