internal override void OnEditCanceled(DataGridItemEventArgs e)
        {
            object item = e.Item;

            DataGridPageManagerBase pageManager = this.RootGroup.GetVirtualPageManager();

            // Compare cached values with current values.  If they are the same, we can clear the old values which in turn will
            // make the item non dirty.
            bool clearIsDirty = true;

            VirtualizedItemValueCollection cachedValues = pageManager.GetCachedValuesForItem(item);

            Debug.Assert(cachedValues != null);

            DataGridItemPropertyCollection itemProperties = this.ItemProperties;

            foreach (DataGridItemPropertyBase itemProperty in itemProperties)
            {
                object currentValue = itemProperty.GetValue(item);

                if (!(object.Equals(currentValue, cachedValues[itemProperty.Name])))
                {
                    clearIsDirty = false;
                    break;
                }
            }

            if (clearIsDirty)
            {
                pageManager.ClearCachedValuesForItem(item);
            }

            base.OnEditCanceled(e);
        }
        internal override void OnEditBegun(DataGridItemEventArgs e)
        {
            object item = e.Item;

            DataGridPageManagerBase pageManager = this.RootGroup.GetVirtualPageManager();

            if (!pageManager.IsItemDirty(item))
            {
                // First time we enter edit on this item.
                DataGridItemPropertyCollection itemProperties = this.ItemProperties;
                int count = itemProperties.Count;

                string[] propertyNames = new string[count];
                object[] cachedValues  = new object[count];

                for (int i = 0; i < count; i++)
                {
                    DataGridItemPropertyBase itemProperty = itemProperties[i];
                    propertyNames[i] = itemProperty.Name;
                    cachedValues[i]  = itemProperty.GetValue(item);
                }

                // Cache the values of the never edited before row.  This will help the developer find the corresponding row
                // in the source when times comes to commit the changes to the data source.
                pageManager.SetCachedValuesForItem(item, propertyNames, cachedValues);
            }

            base.OnEditBegun(e);
        }
        private VirtualList CreateNewVirtualList()
        {
            Debug.Assert(m_isBottomLevel);

            DataGridVirtualizingCollectionViewBase collectionView = this.GetCollectionView();

            DataGridPageManagerBase virtualPageManagerBase = collectionView.RootGroup.GetVirtualPageManager();

            VirtualList virtualItemList = new VirtualList(virtualPageManagerBase, m_virtualItemCount);

            virtualPageManagerBase.LinkVirtualListAndCollectionViewGroup(virtualItemList, this);

            return(virtualItemList);
        }
      public DataGridPageManagerEnumerator( DataGridPageManagerBase dataGridPageManagerBase )
      {
        if( dataGridPageManagerBase == null )
          throw new ArgumentNullException( "dataGridPageManagerBase" );

        m_dataGridPageManagerBase = dataGridPageManagerBase;

        VirtualList[] orderedVirtualLists =
          m_dataGridPageManagerBase.m_virtualListVSCollectionViewGroupDictionary.Keys.OrderBy(
            virtualList => m_dataGridPageManagerBase.m_virtualListVSCollectionViewGroupDictionary[ virtualList ].StartGlobalIndex ).ToArray();

        m_orderedVirtualListEnumerators = new VirtualListEnumerator[ orderedVirtualLists.Length ];

        for( int i = 0; i < orderedVirtualLists.Length; i++ )
        {
          m_orderedVirtualListEnumerators[ i ] = ( VirtualListEnumerator )( ( IEnumerable )orderedVirtualLists[ i ] ).GetEnumerator();
        }
      }
        internal override void OnBeginningEdit(DataGridItemCancelEventArgs e)
        {
            object item = e.Item;

            // We throw instead of setting e.Cancel to True because we do not want to give the developer the chance to set it back to False.
            if (item is EmptyDataItem)
            {
                throw new DataGridException("Cannot begin edit on an empty data item or on an item that has a pending commit async operation.");
            }

            DataGridPageManagerBase pageManager = this.RootGroup.GetVirtualPageManager();

            if (pageManager.IsAsyncCommitQueuedForItem(item))
            {
                throw new DataGridException("Cannot begin edit on an empty data item or on an item that has a pending commit async operation.");
            }

            base.OnBeginningEdit(e);
        }
        internal override void ForceRefresh(bool sendResetNotification, bool initialLoad, bool setCurrentToFirstOnInitialLoad)
        {
            if (this.Refreshing)
            {
                throw new InvalidOperationException("An attempt was made to refresh the DataGridVirtualizingCollectionView while it is already in the process of refreshing.");
            }

            if (this.IsRefreshingDistinctValues)
            {
                throw new InvalidOperationException("An attempt was made to refresh the DataGridVirtualizingCollectionView while it is already in the process of refreshing distinct values.");
            }

            this.SetCurrentEditItem(null);
            int oldCurrentPosition = -1;

            if (!initialLoad)
            {
                this.SaveCurrentBeforeReset(out oldCurrentPosition);
            }

            using (this.DeferCurrencyEvent())
            {
                this.Refreshing = true;
                try
                {
                    lock (this.SyncRoot)
                    {
                        lock (this.DeferredOperationManager)
                        {
                            this.DeferredOperationManager.ClearDeferredOperations();

                            // We explicitly go through base so we do not end-up creating a RootGroup if there is none existing at the moment.
                            DataGridVirtualizingCollectionViewGroupBase rootGroup = base.RootGroup as DataGridVirtualizingCollectionViewGroupBase;
                            if (rootGroup != null)
                            {
                                DataGridPageManagerBase pageManager = rootGroup.GetVirtualPageManager();

                                // The pageManager can be null when no queryable source was set yet.
                                if (pageManager != null)
                                {
                                    // Disconnect the PageManager so that subsequent Items/Count interrogations are not processed.
                                    pageManager.Disconnect();

                                    // Restart all virtual lists.  The DataGridPageManagerBase will make a call to ForceRefresh once everything has been restarted if
                                    // commit operations had to be made.
                                    pageManager.Restart();
                                }
                            }

                            // Ensure to clear the DistinctValues cache when refreshing
                            // since the source could have changed
                            this.ResetDistinctValues();

                            base.RootGroup = this.CreateNewRootGroup();

                            // We set the current item to -1 to prevent the developper to get an invalid position.
                            // We will replace the current item to the correct one later.
                            this.SetCurrentItem(-1, null, false, false);
                        }
                    }
                }
                finally
                {
                    this.Refreshing = false;
                }

                if (initialLoad)
                {
                    this.Loaded = true;
                }
                else
                {
                    this.AdjustCurrencyAfterReset(oldCurrentPosition);
                }

                if (sendResetNotification)
                {
                    this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
                }
            }
        }