internal virtual GroupDescription GetSubGroupBy()
        {
            CollectionView collectionView = this.GetCollectionView();

            ObservableCollection <GroupDescription> groupDescriptions = collectionView.GroupDescriptions;

            int groupDescriptionsCount = (groupDescriptions == null) ? 0 : groupDescriptions.Count;

            if (groupDescriptionsCount == 0)
            {
                return(null);
            }


            DataGridVirtualizingCollectionViewGroupBase parentCollectionViewGroup = this.Parent;

            int level = 0;

            while (parentCollectionViewGroup != null)
            {
                level++;
                parentCollectionViewGroup = parentCollectionViewGroup.Parent;
            }

            Debug.Assert(groupDescriptionsCount >= level);

            return(groupDescriptions[level]);
        }
        protected void UnlinkVirtualListAndCollectionViewGroup(VirtualList virtualList)
        {
            DataGridVirtualizingCollectionViewGroupBase collectionViewGroup = null;

            if (m_virtualListVSCollectionViewGroupDictionary.TryGetValue(virtualList, out collectionViewGroup))
            {
                CollectionChangedEventManager.RemoveListener(virtualList, collectionViewGroup);
                m_virtualListVSCollectionViewGroupDictionary.Remove(virtualList);
            }
        }
        private void RaiseCollectionViewOnCommitItems(VirtualPage dispatchedPage, AsyncCommitInfo dispatchedCommitInfo)
        {
            DataGridVirtualizingCollectionViewBase collectionView = this.CollectionView as DataGridVirtualizingCollectionViewBase;

            DataGridVirtualizingCollectionViewGroupBase collectionViewGroup =
                this.GetLinkedCollectionViewGroup(dispatchedPage.ParentVirtualList) as DataGridVirtualizingCollectionViewGroupBase;

            Debug.Assert((collectionViewGroup != null) && (collectionView != null));

            collectionView.OnCommitItems(dispatchedCommitInfo);
        }
 internal DataGridVirtualizingCollectionViewGroupBase(
     object name,
     int initialItemsCount,
     int startGlobalIndex,
     DataGridVirtualizingCollectionViewGroupBase parent,
     int level,
     bool isBottomLevel)
     : base(name)
 {
     m_parent           = parent;
     m_level            = level;
     m_isBottomLevel    = isBottomLevel;
     m_virtualItemCount = initialItemsCount;
     m_startGlobalIndex = startGlobalIndex;
 }
 internal DataGridVirtualizingCollectionViewGroupBase(
   object name,
   int initialItemsCount,
   int startGlobalIndex,
   DataGridVirtualizingCollectionViewGroupBase parent,
   int level,
   bool isBottomLevel )
   : base( name )
 {
   m_parent = parent;
   m_level = level;
   m_isBottomLevel = isBottomLevel;
   m_virtualItemCount = initialItemsCount;
   m_startGlobalIndex = startGlobalIndex;
 }
        private int GetSubLevelCount()
        {
            CollectionView collectionView = this.GetCollectionView();

            ObservableCollection <GroupDescription> groupDescriptions = collectionView.GroupDescriptions;

            int groupDescriptionsCount = (groupDescriptions == null) ? 0 : groupDescriptions.Count;

            DataGridVirtualizingCollectionViewGroupBase parentCollectionViewGroup = this.Parent;

            int level = 0;

            while (parentCollectionViewGroup != null)
            {
                level++;
                parentCollectionViewGroup = parentCollectionViewGroup.Parent;
            }

            Debug.Assert(groupDescriptionsCount >= level);

            return(groupDescriptionsCount - level);
        }
        internal static SelectionRange GetRange(this CollectionViewGroup collectionViewGroup, DataGridContext dataGridContext)
        {
            int startIndex = -1;
            int endIndex   = -1;

            DataGridVirtualizingCollectionViewGroupBase dataGridVirtualizingCollectionViewGroupBase = collectionViewGroup as DataGridVirtualizingCollectionViewGroupBase;
            DataGridCollectionViewGroup dataGridCollectionViewGroup = collectionViewGroup as DataGridCollectionViewGroup;

            if (dataGridVirtualizingCollectionViewGroupBase != null)
            {
                startIndex = dataGridVirtualizingCollectionViewGroupBase.StartGlobalIndex;
                endIndex   = startIndex + dataGridVirtualizingCollectionViewGroupBase.VirtualItemCount - 1;
            }
            else if (dataGridCollectionViewGroup != null)
            {
                startIndex = dataGridCollectionViewGroup.GetFirstRawItemGlobalSortedIndex();
                endIndex   = startIndex + dataGridCollectionViewGroup.GlobalRawItemCount - 1;
            }
            else if (collectionViewGroup.ItemCount > 0)
            {
                if (dataGridContext == null)
                {
                    throw new DataGridInternalException("This collectionViewGroup require a DataGridContext instance");
                }

                var firstItem = collectionViewGroup.GetFirstLeafItem();
                var lastItem  = collectionViewGroup.GetLastLeafItem();

                if (firstItem != null && lastItem != null)
                {
                    startIndex = dataGridContext.Items.IndexOf(firstItem);
                    endIndex   = dataGridContext.Items.IndexOf(lastItem);
                }
            }

            return((startIndex >= 0) && (startIndex <= endIndex)
        ? new SelectionRange(startIndex, endIndex)
        : SelectionRange.Empty);
        }
        public static IList <object> GetItems(this CollectionViewGroup collectionViewGroup)
        {
            DataGridVirtualizingCollectionViewGroupBase dataGridVirtualizingCollectionViewGroupBase = collectionViewGroup as DataGridVirtualizingCollectionViewGroupBase;

            if (dataGridVirtualizingCollectionViewGroupBase != null)
            {
                return(dataGridVirtualizingCollectionViewGroupBase.VirtualItems);
            }

            DataGridCollectionViewGroup dataGridCollectionViewGroup = collectionViewGroup as DataGridCollectionViewGroup;

            if (dataGridCollectionViewGroup != null)
            {
                // The Items property of the DataGridCollectionViewGroup has been optimized
                // to allow faster IndexOf and Contains. Since this property we could not
                // override the property, we had to new it thus, we need to cast the CollectionViewGroup
                // in the right type before acecssing the property.
                return(dataGridCollectionViewGroup.Items);
            }

            return(collectionViewGroup.Items);
        }
        public int GetGlobalIndexOf(object item)
        {
            ReadOnlyCollection <VirtualList> virtualItemLists = this.ManagedLists;
            int virtualItemListsCount = virtualItemLists.Count;

            for (int i = 0; i < virtualItemListsCount; i++)
            {
                VirtualList localList  = virtualItemLists[i];
                int         localIndex = localList.IndexOf(item);

                if (localIndex >= 0)
                {
                    Debug.Assert(m_virtualListVSCollectionViewGroupDictionary.ContainsKey(localList));

                    DataGridVirtualizingCollectionViewGroupBase dgvcvg = m_virtualListVSCollectionViewGroupDictionary[localList];

                    return(localIndex + dgvcvg.StartGlobalIndex);
                }
            }

            return(-1);
        }
        private object OperateOnGlobalIndex(int index, Func <int, DataGridVirtualizingCollectionViewGroupBase, object> function)
        {
            this.EnsureProtectedVirtualItems();

            if (this.IsBottomLevel)
            {
                return(function(index, this));
            }
            else
            {
                // The Count property of the virtualItems collection will return the sub-group count since this is not the bottom level.
                int count = m_protectedVirtualItems.Count;

                for (int i = 0; i < count; i++)
                {
                    DataGridVirtualizingCollectionViewGroupBase subGroup = m_protectedVirtualItems[i] as DataGridVirtualizingCollectionViewGroupBase;

                    if (subGroup == null)
                    {
                        throw new InvalidOperationException("Sub-group cannot be null (Nothing in Visual Basic).");
                    }

                    // VirtualItemCount will return the sum of data items contained in this group and its possible subgroups.
                    int subGroupItemCount = subGroup.VirtualItemCount;

                    if (index < subGroupItemCount)
                    {
                        return(subGroup.OperateOnGlobalIndex(index, function));
                    }

                    index -= subGroupItemCount;
                }
            }

            throw new ArgumentOutOfRangeException("index");
        }
        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));
                }
            }
        }
        internal void LinkVirtualListAndCollectionViewGroup(VirtualList virtualItemList, DataGridVirtualizingCollectionViewGroupBase collectionViewGroup)
        {
            Debug.Assert(!m_virtualListVSCollectionViewGroupDictionary.ContainsKey(virtualItemList));
            Debug.Assert(!m_virtualListVSCollectionViewGroupDictionary.ContainsValue(collectionViewGroup));

            m_virtualListVSCollectionViewGroupDictionary.Add(virtualItemList, collectionViewGroup);

            CollectionChangedEventManager.AddListener(virtualItemList, collectionViewGroup);
        }