internal RawItem GetRawItemAtGlobalSortedIndex(int index)
        {
            if (this.IsBottomLevel)
            {
                return(m_sortedRawItems[index]);
            }
            else
            {
                foreach (object value in this.ProtectedItems)
                {
                    DataGridCollectionViewGroup subGroup = value as DataGridCollectionViewGroup;

                    int subGroupCount = subGroup.GlobalRawItemCount;

                    if (index < subGroupCount)
                    {
                        return(subGroup.GetRawItemAtGlobalSortedIndex(index));
                    }

                    index -= subGroupCount;
                }
            }

            throw new ArgumentOutOfRangeException("index");
        }
        private void RemoveGroup(DataGridCollectionViewGroup group)
        {
            if (group == null)
            {
                throw new ArgumentNullException("group");
            }

            Debug.Assert(this == group.m_parent);

            // We do not remove group forced in SubGroupBy.GroupNames
            if (group.UnsortedIndex < this.SubGroupBy.GroupNames.Count)
            {
                return;
            }

            Debug.Assert(!this.IsBottomLevel);
            Debug.Assert((group.m_globalRawItemCount == 0) && (group.ProtectedItemCount == 0));

            m_subGroups.Remove(DataGridCollectionViewGroup.GetHashKeyFromName(group.Name));

            this.ProtectedItemCount--;
            this.ProtectedItems.Remove(group);

            if ((m_subGroups.Count == 0) && (m_parent != null))
            {
                m_parent.RemoveGroup(this);
            }
        }
        internal bool Contains(object item)
        {
            var group = item as DataGridCollectionViewGroup;

            if (group != null)
            {
                //Must make sure the group the group is ref equals, because there can be groups with a null name at more than one level.
                DataGridCollectionViewGroup foundGroup;
                if (m_subGroups.TryGetValue(DataGridCollectionViewGroup.GetHashKeyFromName(group.Name), out foundGroup))
                {
                    return(foundGroup == group);
                }

                return(false);
            }

            DataGridCollectionView collectionView = this.GetCollectionView();

            if (collectionView != null)
            {
                RawItem rawItem = collectionView.GetFirstRawItemFromDataItem(item);
                if (rawItem != null)
                {
                    return(rawItem.ParentGroup == this);
                }
            }

            return(false);
        }
        public override int Compare(int xDataIndex, int yDataIndex)
        {
            DataGridCollectionViewGroup xGroup = m_groups[xDataIndex];
            DataGridCollectionViewGroup yGroup = m_groups[yDataIndex];

            return(m_groupSortedComparer.Compare(xGroup, yGroup));
        }
        internal int GetFirstRawItemGlobalSortedIndex()
        {
            int index = 0;
            DataGridCollectionViewGroup group        = this;
            DataGridCollectionViewGroup parent       = this.Parent;
            DataGridCollectionViewGroup currentGroup = null;

            while (parent != null)
            {
                foreach (object value in parent.ProtectedItems)
                {
                    if (value == group)
                    {
                        break;
                    }

                    currentGroup = value as DataGridCollectionViewGroup;

                    index += currentGroup.GlobalRawItemCount;
                }

                group  = parent;
                parent = parent.Parent;
            }

            return(index);
        }
        internal virtual void InsertRawItem(int index, RawItem rawItem)
        {
            Debug.Assert(this.IsBottomLevel);

            m_globalRawItemCount++;
            DataGridCollectionViewGroup parent = m_parent;

            while (parent != null)
            {
                parent.m_globalRawItemCount++;
                parent = parent.m_parent;
            }

            int count = m_sortedRawItems.Count;

            for (int i = index; i < count; i++)
            {
                m_sortedRawItems[i].SetSortedIndex(i + 1);
            }

            m_sortedRawItems.Insert(index, rawItem);
            rawItem.SetParentGroup(this);
            rawItem.SetSortedIndex(index);

            this.ProtectedItemCount++;
            this.ProtectedItems.Insert(index, rawItem.DataItem);
        }
        private void InsertGroup(int index, DataGridCollectionViewGroup group)
        {
            Debug.Assert(!this.IsBottomLevel);

            m_subGroups.Add(DataGridCollectionViewGroup.GetHashKeyFromName(group.Name), group);
            this.ProtectedItemCount++;
            this.ProtectedItems.Insert(index, group);
        }
            internal OptimizedReadOnlyObservableCollection(DataGridCollectionViewGroup dataGridCollectionViewGroup)
                : base(dataGridCollectionViewGroup.ProtectedItems)
            {
                if (dataGridCollectionViewGroup == null)
                {
                    throw new ArgumentNullException("dataGridCollectionViewGroup");
                }

                m_dataGridCollectionViewGroup = dataGridCollectionViewGroup;
            }
 private DataGridCollectionViewGroup(object name, DataGridCollectionViewGroup parent, int unsortedIndex, int rawCapacity, int groupCapacity)
     : base(name)
 {
     m_parent         = parent;
     m_unsortedIndex  = unsortedIndex;
     m_protectedItems = ObservableCollectionHelper.GetItems(base.ProtectedItems);
     m_protectedItemsCollectionChanged = ObservableCollectionHelper.GetCollectionChanged(base.ProtectedItems);
     m_optimizedItems = new OptimizedReadOnlyObservableCollection(this);
     m_subGroups      = new Dictionary <object, DataGridCollectionViewGroup>(groupCapacity);
     m_sortedRawItems = new List <RawItem>(rawCapacity);
 }
        private int BinarySearchGroup(DataGridCollectionViewGroup value, IComparer <DataGridCollectionViewGroup> comparer)
        {
            if (comparer == null)
            {
                throw new ArgumentNullException("comparer");
            }

            int low = 0;
            int hi  = (this.ProtectedItemCount) - 1;
            int median;
            int compareResult;

            while (low <= hi)
            {
                median = (low + ((hi - low) >> 1));

                DataGridCollectionViewGroup medianGroup = this.ProtectedItems[median] as DataGridCollectionViewGroup;

                if (medianGroup == value)
                {
                    if (low == hi)
                    {
                        return(low);
                    }

                    return(median);
                }

                try
                {
                    compareResult = comparer.Compare(medianGroup, value);
                }
                catch (Exception exception)
                {
                    throw new InvalidOperationException("IComparer has failed to compare the values.", exception);
                }

                if (compareResult == 0)
                {
                    return(median);
                }
                if (compareResult < 0)
                {
                    low = median + 1;
                }
                else
                {
                    hi = median - 1;
                }
            }

            return(~low);
        }
Example #11
0
        private DataGridCollectionViewGroup MoveToFirstLeafGroup(DataGridCollectionViewGroup referenceGroup, int index)
        {
            while (!referenceGroup.IsBottomLevel)
            {
                referenceGroup = referenceGroup.Items[index] as DataGridCollectionViewGroup;
                m_currentGroupIndex.Push(index);

                if (index != 0)
                {
                    index = 0;
                }
            }

            return(referenceGroup);
        }
        internal DataGridCollectionViewGroup GetGroup(
            RawItem rawItem,
            int level,
            CultureInfo culture,
            ObservableCollection <GroupDescription> groupByList,
            List <GroupSortComparer> groupSortComparers)
        {
            // If sortComparers is null, we are in massive group creation, no order check.

            if (this.IsBottomLevel)
            {
                throw new InvalidOperationException("An attempt was made to get a group for which a GroupDescription has not been provided.");
            }

            object groupName = m_subGroupBy.GroupNameFromItem(rawItem.DataItem, level, culture);
            DataGridCollectionViewGroup group;

            if ((m_subGroupBy is DataGridGroupDescription) || (m_subGroupBy is PropertyGroupDescription))
            {
                m_subGroups.TryGetValue(DataGridCollectionViewGroup.GetHashKeyFromName(groupName), out group);
            }
            else
            {
                //If dealing with an unknown GroupDescription type, use the standard method to retrieve a group, in case group retrival is handle differently.
                group = null;

                foreach (var tempGroup in m_subGroups.Values)
                {
                    if (m_subGroupBy.NamesMatch(tempGroup.Name, groupName))
                    {
                        group = tempGroup;
                        break;
                    }
                }
            }

            if (group == null)
            {
                group = this.CreateSubGroup(groupName, level, groupByList, groupSortComparers);
            }

            return(group);
        }
        public void InvalidateGroupStats(DataGridCollectionViewGroup group, bool calculateAllStats = false)
        {
            if (group == null)
            {
                return;
            }

            lock (this)
            {
                if (this.RefreshPending)
                {
                    return;
                }

                DataGridCollectionViewGroup parent = group;

                while (parent != null)
                {
                    if (!m_invalidatedGroups.Contains(parent))
                    {
                        m_invalidatedGroups.Add(parent);
                    }

                    parent.ClearStatFunctionsResult();
                    parent.CalculateAllStats = calculateAllStats;
                    parent = parent.Parent;
                }

                if (m_dispatcher != null)
                {
                    if (m_dispatcherOperation == null)
                    {
                        m_dispatcherOperation          = m_dispatcher.BeginInvoke(DispatcherPriority.DataBind, new DispatcherOperationCallback(this.Dispatched_Process), null);
                        m_dispatcherOperationStartTime = DateTime.UtcNow;
                    }
                    else
                    {
                        m_hasNewOperationsSinceStartTime = true;
                    }
                }
            }
        }
        internal virtual void RemoveRawItemAt(int index)
        {
            Debug.Assert(this.IsBottomLevel);
            Debug.Assert(m_sortedRawItems.Count > 0);

            int count = m_sortedRawItems.Count;

            if (count == 0)
            {
                return;
            }

            if (index != -1)
            {
                m_globalRawItemCount--;
                DataGridCollectionViewGroup parent = m_parent;

                while (parent != null)
                {
                    parent.m_globalRawItemCount--;
                    parent = parent.Parent;
                }

                for (int i = index + 1; i < count; i++)
                {
                    m_sortedRawItems[i].SetSortedIndex(i - 1);
                }

                RawItem rawItem = m_sortedRawItems[index];
                rawItem.SetParentGroup(null);
                rawItem.SetSortedIndex(-1);
                m_sortedRawItems.RemoveAt(index);

                this.ProtectedItemCount--;
                this.ProtectedItems.RemoveAt(index);

                if ((this.ProtectedItemCount == 0) && (m_parent != null))
                {
                    m_parent.RemoveGroup(this);
                }
            }
        }
        internal void SortGroups(List <GroupSortComparer> groupSortComparers, int level)
        {
            int itemCount = this.ProtectedItemCount;

            if (itemCount == 0)
            {
                return;
            }

            int[] indexes;
            indexes = new int[itemCount + 1];
            for (int i = 0; i < itemCount; i++)
            {
                indexes[i] = i;
            }

            DataGridCollectionViewGroup[] subGroupsArray = new DataGridCollectionViewGroup[itemCount];
            m_subGroups.Values.CopyTo(subGroupsArray, 0);

            // "Weak heap sort" sort array[0..NUM_ELEMENTS-1] to array[1..NUM_ELEMENTS]
            DataGridCollectionViewGroupSort collectionViewSort = new DataGridCollectionViewGroupSort(indexes, groupSortComparers[level], subGroupsArray);

            collectionViewSort.Sort(itemCount);
            level++;
            m_protectedItems.Clear();

            for (int i = 1; i <= itemCount; i++)
            {
                DataGridCollectionViewGroup group = subGroupsArray[indexes[i]];

                // Sort sub groups
                if (!group.IsBottomLevel)
                {
                    group.SortGroups(groupSortComparers, level);
                }

                m_protectedItems.Add(group);
            }

            this.ProtectedItemCount = m_protectedItems.Count;
            m_protectedItemsCollectionChanged.Invoke(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
        }
        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);
        }
        private DataGridCollectionViewGroup CreateSubGroup(object groupName, int level, ObservableCollection <GroupDescription> groupByList,
                                                           List <GroupSortComparer> groupSortComparers)
        {
            // If sortComparers is null, we are in massive group creation, no order check.
            DataGridCollectionViewGroup group = new DataGridCollectionViewGroup(groupName, this, m_nextSubGroupUnsortedIndex);

            unchecked
            {
                m_nextSubGroupUnsortedIndex++;
            }

            int index;

            if (groupSortComparers == null)
            {
                Debug.Assert(this.ProtectedItemCount == this.ProtectedItems.Count);
                index = this.ProtectedItemCount;
            }
            else
            {
                index = this.BinarySearchGroup(group, groupSortComparers[level]);

                if (index < 0)
                {
                    index = ~index;
                }
            }

            level++;

            if (level < groupByList.Count)
            {
                group.SetSubGroupBy(groupByList[level]);
                group.CreateFixedGroupNames(level, groupByList, groupSortComparers);
            }

            this.InsertGroup(index, group);
            return(group);
        }
Example #18
0
 internal void SetParentGroup(DataGridCollectionViewGroup parentGroup)
 {
     m_parentGroup = parentGroup;
 }
        internal void SortItems(
            SortDescriptionInfo[] sortDescriptionInfos,
            List <GroupSortComparer> groupSortComparers,
            int level,
            List <RawItem> globalRawItems,
            DataGridCollectionViewGroup newSortedGroup)
        {
            int itemCount = this.ProtectedItemCount;

            if (itemCount == 0)
            {
                return;
            }

            if (this.IsBottomLevel)
            {
                int[] indexes;
                indexes = new int[itemCount + 1];
                for (int i = 0; i < itemCount; i++)
                {
                    indexes[i] = m_sortedRawItems[i].Index;
                }

                // "Weak heap sort" sort array[0..NUM_ELEMENTS-1] to array[1..NUM_ELEMENTS]
                DataGridCollectionViewSort collectionViewSort = new DataGridCollectionViewSort(indexes, sortDescriptionInfos);

                collectionViewSort.Sort(itemCount);
                int index = 0;

                for (int i = 1; i <= itemCount; i++)
                {
                    newSortedGroup.InsertRawItem(index, globalRawItems[indexes[i]]);
                    index++;
                }
            }
            else
            {
                int[] indexes;
                indexes = new int[itemCount + 1];
                for (int i = 0; i < itemCount; i++)
                {
                    indexes[i] = i;
                }

                DataGridCollectionViewGroup[] subGroupsArray = new DataGridCollectionViewGroup[itemCount];
                m_subGroups.Values.CopyTo(subGroupsArray, 0);

                // "Weak heap sort" sort array[0..NUM_ELEMENTS-1] to array[1..NUM_ELEMENTS]
                DataGridCollectionViewGroupSort collectionViewSort = new DataGridCollectionViewGroupSort(indexes, groupSortComparers[level], subGroupsArray);

                collectionViewSort.Sort(itemCount);
                int index = 0;
                level++;

                for (int i = 1; i <= itemCount; i++)
                {
                    DataGridCollectionViewGroup oldGroup = subGroupsArray[indexes[i]];
                    DataGridCollectionViewGroup newGroup = new DataGridCollectionViewGroup(oldGroup, newSortedGroup);

                    // Sort sub items
                    oldGroup.SortItems(sortDescriptionInfos, groupSortComparers, level, globalRawItems, newGroup);

                    newSortedGroup.InsertGroup(index, newGroup);
                    index++;
                }
            }
        }
 protected DataGridCollectionViewGroup(DataGridCollectionViewGroup template, DataGridCollectionViewGroup parent)
     : this(template.Name, parent, template.m_unsortedIndex, template.m_sortedRawItems.Count, template.m_subGroups.Count)
 {
     m_nextSubGroupUnsortedIndex = template.m_nextSubGroupUnsortedIndex;
     m_subGroupBy = template.m_subGroupBy;
 }
 private DataGridCollectionViewGroup(object name, DataGridCollectionViewGroup parent, int unsortedIndex)
     : this(name, parent, unsortedIndex, 4, 4)
 {
 }