private void AddToSubgroups(object item, CollectionViewGroupInternal group, int level, bool loading) { object name = this.GetGroupName(item, group.GroupBy, level); if (name == UseAsItemDirectly) { if (loading) { group.Add(item); } else { int index = group.Insert(item, item, this.ActiveComparer); int num2 = group.LeafIndexFromItem(item, index); this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(0, item, num2)); } } else { ICollection is2 = name as ICollection; if (is2 == null) { this.AddToSubgroup(item, group, level, name, loading); } else { foreach (object obj3 in is2) { this.AddToSubgroup(item, group, level, obj3, loading); } } } }
private void AddToSubgroup(object item, CollectionViewGroupInternal group, int level, object name, bool loading) { CollectionViewGroupInternal internal2; int num = this._isDataInGroupOrder ? group.LastIndex : 0; int count = group.Items.Count; while (num < count) { internal2 = group.Items[num] as CollectionViewGroupInternal; if ((internal2 != null) && group.GroupBy.NamesMatch(internal2.Name, name)) { group.LastIndex = num; this.AddToSubgroups(item, internal2, level + 1, loading); return; } num++; } internal2 = new CollectionViewGroupInternal(name, group); this.InitializeGroup(internal2, level + 1, item); if (loading) { group.Add(internal2); group.LastIndex = num; } else { group.Insert(internal2, item, this.ActiveComparer); } this.AddToSubgroups(item, internal2, level + 1, loading); }
/// <summary> /// Remove an item from the direct children of a group. /// </summary> /// <param name="group">Group to remove item from</param> /// <param name="item">Item to remove</param> /// <returns>True if item could not be removed</returns> private bool RemoveFromGroupDirectly(CollectionViewGroupInternal group, object item) { int leafIndex = group.Remove(item, true); if (leafIndex >= 0) { this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item, leafIndex)); return(false); } else { return(true); } }
private void RemoveItemFromSubgroupsByExhaustiveSearch(CollectionViewGroupInternal group, object item) { if (!this.RemoveFromGroupDirectly(group, item)) { return; } for (int index = group.Items.Count - 1; index >= 0; --index) { CollectionViewGroupInternal group1 = group.Items[index] as CollectionViewGroupInternal; if (group1 != null) { this.RemoveItemFromSubgroupsByExhaustiveSearch(group1, item); } } }
//------------------------------------------------------ // // Private Methods // //------------------------------------------------------ /// <summary> /// Removes an empty group from the PagedCollectionView grouping /// </summary> /// <param name="group">Empty subgroup to remove</param> private static void RemoveEmptyGroup(CollectionViewGroupInternal group) { CollectionViewGroupInternal parent = group.Parent; if (parent != null) { GroupDescription groupBy = parent.GroupBy; int index = parent.ProtectedItems.IndexOf(group); // remove the subgroup unless it is one of the explicit groups if (index >= groupBy.GroupNames.Count) { parent.Remove(group, false); } } }
// Sort the data source with a default comparer void Sort(PropertySortDescription operation) { if (VerifyComparable(operation))// if we can't compare data, we don't try to sort { ListSortDirection directionBackup = operation.Direction; operation.Direction = _operations.GetFixedDirection(operation); Collection <object> childItems = new Collection <object>(); //todo: replace with a sort algorithm that is O(NLogN), for example by creating a List<T> and calling List<T>.Sort(comparer). foreach (object item in Items) { int index; // we get the value of the sorting property on this item to allow comparison (if we are here, we know that data is comparable) // then we get the position where we need to insert this item if (CSHTML5.Interop.IsRunningInTheSimulator) { IComparable value = (IComparable)GetValue(item, operation); index = GetPosIndex_SimulatorOnly(operation, value, 0, childItems.Count, childItems); } else { dynamic value = GetValue(item, operation); index = GetPosIndex_JSOnly(operation, value, 0, childItems.Count, childItems); } childItems.Insert(index, item); } operation.Direction = directionBackup; // Pass the result of the sort to a child CollectionViewGroup in order to apply other operations (such as sort) if any: CollectionViewGroupInternal newView = new CollectionViewGroupInternal(childItems, this, _operations); _operations.Requester.AddView(newView); // create child branch after sorting operation } else { CollectionViewGroupInternal newView = new CollectionViewGroupInternal(Items, this, _operations); _operations.Requester.AddView(newView); // create child branch without sorting } }
/// <summary> /// Finds the index of the specified item /// </summary> /// <param name="item">Item we are looking for</param> /// <param name="seed">Seed of the item we are looking for</param> /// <param name="comparer">Comparer used to find the item</param> /// <param name="low">Low range of item index</param> /// <param name="high">High range of item index</param> /// <returns>Index of the specified item</returns> protected virtual int FindIndex(object item, object seed, IComparer comparer, int low, int high) { int index; if (comparer != null) { ListComparer listComparer = comparer as ListComparer; if (listComparer != null) { // reset the IListComparer before each search. This cannot be done // any less frequently (e.g. in Root.AddToSubgroups), due to the // possibility that the item may appear in more than one subgroup. listComparer.Reset(); } CollectionViewGroupComparer groupComparer = comparer as CollectionViewGroupComparer; if (groupComparer != null) { // reset the CollectionViewGroupComparer before each search. This cannot be done // any less frequently (e.g. in Root.AddToSubgroups), due to the // possibility that the item may appear in more than one subgroup. groupComparer.Reset(); } for (index = low; index < high; ++index) { CollectionViewGroupInternal subgroup = this.ProtectedItems[index] as CollectionViewGroupInternal; object seed1 = (subgroup != null) ? subgroup.SeedItem : this.ProtectedItems[index]; if (seed1 == DependencyProperty.UnsetValue) { continue; } if (comparer.Compare(seed, seed1) < 0) { break; } } } else { index = high; } return(index); }
// Filter the data source with a predicate void Filter(Predicate <Object> predicate) { // Create a new collection with the result of the filtering: Collection <object> childItems = new Collection <object>(); foreach (object obj in Items) { if (predicate(obj)) { childItems.Add(obj); } } // Pass the result of the filtering to a child CollectionViewGroup in order to apply other operations (such as sort) if any: CollectionViewGroupInternal newView = new CollectionViewGroupInternal(childItems, this, _operations); _operations.Requester.AddView(newView); // create child branch }
// Token: 0x060026E6 RID: 9958 RVA: 0x000B848C File Offset: 0x000B668C protected override int GetSizeOfSetCore() { int num = base.GetSizeOfSetCore(); if (num == -1) { GroupItem groupItem = (GroupItem)base.Owner; CollectionViewGroupInternal collectionViewGroupInternal = groupItem.GetValue(ItemContainerGenerator.ItemForItemContainerProperty) as CollectionViewGroupInternal; if (collectionViewGroupInternal != null) { CollectionViewGroup parent = collectionViewGroupInternal.Parent; if (parent != null) { num = parent.Items.Count; } } } return(num); }
// create all the operation tree with a new source void CreateTree() { _views.Clear(); _operations = new INTERNAL_Operations(this); // we reset the operations to do ICollection <object> newCollection = new Collection <object>(); foreach (object obj in _originalDataSource) { newCollection.Add(obj); } CollectionViewGroupInternal treeRoot = new CollectionViewGroupInternal(newCollection.ToList <object>(), null, _operations); _views.Add(treeRoot); // we make sure that the treeRoot is the last element to be added to the _views collection because the call to the CollectionViewGroupInternal contructor creates a tree via recursion, which by itself adds the branches in _views. ConstrainIndexToRemainInsideAllowedRange(); // because some leaves can disappear if it's not the first generation (ie. if it has already been refreshed once) }
private void InitializeGroup(CollectionViewGroupInternal group, GroupDescription parentDescription, int level) { GroupDescription groupDescription = this.GetGroupDescription((CollectionViewGroup)group, parentDescription, level); group.GroupBy = groupDescription; ObservableCollection <object> observableCollection = groupDescription != null ? groupDescription.GroupNames : (ObservableCollection <object>)null; if (observableCollection != null) { int index = 0; for (int count = observableCollection.Count; index < count; ++index) { CollectionViewGroupInternal group1 = new CollectionViewGroupInternal(observableCollection[index], group); this.InitializeGroup(group1, groupDescription, level + 1); group.Add((object)group1); } } group.LastIndex = 0; }
/// <summary> /// The item did not appear in one or more of the subgroups it /// was supposed to. This can happen if the item's properties /// change so that the group names we used to insert it are /// different from the names used to remove it. If this happens, /// remove the item the hard way. /// </summary> /// <param name="group">Group to remove item from</param> /// <param name="item">Item to remove</param> private void RemoveItemFromSubgroupsByExhaustiveSearch(CollectionViewGroupInternal group, object item) { // try to remove the item from the direct children // this function only returns true if it failed to remove from group directly // in which case we will step through and search exhaustively if (this.RemoveFromGroupDirectly(group, item)) { // if that didn't work, recurse into each subgroup // (loop runs backwards in case an entire group is deleted) for (int k = group.Items.Count - 1; k >= 0; --k) { CollectionViewGroupInternal subgroup = group.Items[k] as CollectionViewGroupInternal; if (subgroup != null) { this.RemoveItemFromSubgroupsByExhaustiveSearch(subgroup, item); } } } }
//------------------------------------------------------ // // Private Methods // //------------------------------------------------------ /// <summary> /// Add an item to the subgroup with the given name /// </summary> /// <param name="item">Item to add</param> /// <param name="group">Group to add item to</param> /// <param name="level">The level of grouping.</param> /// <param name="name">Name of subgroup to add to</param> /// <param name="loading">Whether we are currently loading</param> private void AddToSubgroup(object item, CollectionViewGroupInternal group, int level, object name, bool loading) { CollectionViewGroupInternal subgroup; int index = (this._isDataInGroupOrder) ? group.LastIndex : 0; // find the desired subgroup for (int n = group.Items.Count; index < n; ++index) { subgroup = group.Items[index] as CollectionViewGroupInternal; if (subgroup == null) { continue; // skip children that are not groups } if (group.GroupBy.NamesMatch(subgroup.Name, name)) { group.LastIndex = index; this.AddToSubgroups(item, subgroup, level + 1, loading); return; } } // the item didn't match any subgroups. Create a new subgroup and add the item. subgroup = new CollectionViewGroupInternal(name, group); this.InitializeGroup(subgroup, level + 1, item); if (loading) { group.Add(subgroup); group.LastIndex = index; } else { // using insert will find the correct sort index to // place the subgroup, and will default to the last // position if no ActiveComparer is specified group.Insert(subgroup, item, this.ActiveComparer); } this.AddToSubgroups(item, subgroup, level + 1, loading); }
/// <summary> /// Gets the position of this GroupItem within a set. /// </summary> /// <remarks> /// Gets the CollectionViewGroupInternal linked to this groupItem via ItemForItemContainerProperty, /// this collection describes the elements belonging to this GroupItem, we need the collection this /// GroupItem belongs to, so we look one level up using Parent. /// </remarks> override protected int GetPositionInSetCore() { int positionInSet = base.GetPositionInSetCore(); if (positionInSet == AutomationProperties.AutomationPositionInSetDefault) { GroupItem groupItem = (GroupItem)Owner; CollectionViewGroupInternal group = groupItem.GetValue(ItemContainerGenerator.ItemForItemContainerProperty) as CollectionViewGroupInternal; if (group != null) { CollectionViewGroup parent = group.Parent; if (parent != null) { positionInSet = parent.Items.IndexOf(group) + 1; } } } return(positionInSet); }
/// <summary> /// Gets the size of a set that contains this GroupItem. /// </summary> /// <remarks> /// Gets the CollectionViewGroupInternal linked to this groupItem via ItemForItemContainerProperty, /// this collection describes the elements belonging to this GroupItem, we need the collection this /// GroupItem belongs to, so we look one level up using Parent. /// </remarks> override protected int GetSizeOfSetCore() { int sizeOfSet = base.GetSizeOfSetCore(); if (sizeOfSet == AutomationProperties.AutomationSizeOfSetDefault) { GroupItem groupItem = (GroupItem)Owner; CollectionViewGroupInternal group = groupItem.GetValue(ItemContainerGenerator.ItemForItemContainerProperty) as CollectionViewGroupInternal; if (group != null) { CollectionViewGroup parent = group.Parent; if (parent != null) { sizeOfSet = parent.Items.Count; } } } return(sizeOfSet); }
private bool RemoveFromSubgroup(object item, CollectionViewGroupInternal group, int level, object name) { object groupNameKey = this.GetGroupNameKey(name, group); CollectionViewGroupInternal subgroupFromMap; if ((subgroupFromMap = group.GetSubgroupFromMap(groupNameKey)) != null && group.GroupBy.NamesMatch(subgroupFromMap.Name, name)) { return(this.RemoveFromSubgroups(item, subgroupFromMap, level + 1)); } int index = 0; for (int count = group.Items.Count; index < count; ++index) { CollectionViewGroupInternal group1 = group.Items[index] as CollectionViewGroupInternal; if (group1 != null && group.GroupBy.NamesMatch(group1.Name, name)) { return(this.RemoveFromSubgroups(item, group1, level + 1)); } } return(true); }
/// <summary> /// MoveNext implementation for IEnumerator /// </summary> /// <returns>Returns whether the MoveNext operation was successful</returns> bool IEnumerator.MoveNext() { Debug.Assert(this._group != null, "_group should have been initialized in constructor"); // check for invalidated enumerator if (this._group._version != this._version) { throw new InvalidOperationException(); } // move forward to the next leaf while (this._subEnum == null || !this._subEnum.MoveNext()) { // done with the current top-level item. Move to the next one. ++this._index; if (this._index >= this._group.Items.Count) { return(false); } CollectionViewGroupInternal subgroup = this._group.Items[this._index] as CollectionViewGroupInternal; if (subgroup == null) { // current item is a leaf - it's the new Current this._current = this._group.Items[this._index]; this._subEnum = null; return(true); } else { // current item is a subgroup - get its enumerator this._subEnum = subgroup.GetLeafEnumerator(); } } // the loop terminates only when we have a subgroup enumerator // positioned at the new Current item this._current = this._subEnum.Current; return(true); }
// Filter the data source using an event (the user sets e.Accepted to true or false in the event handler): void Filter(FilterEventHandler logicMethod) { // Create a new collection with the result of the filtering: Collection <object> childItems = new Collection <object>(); foreach (object obj in Items) { FilterEventArgs args = new FilterEventArgs(obj); logicMethod(this, args); if (args.Accepted) { childItems.Add(obj); } } // Pass the result of the filtering to a child CollectionViewGroup in order to apply other operations (such as sort) if any: CollectionViewGroupInternal newView = new CollectionViewGroupInternal(childItems, this, _operations); _operations.Requester.AddView(newView); // create child branch }
private void AddToSubgroup(object item, LiveShapingItem lsi, CollectionViewGroupInternal group, int level, object name, bool loading) { int index = !loading || !this.IsDataInGroupOrder ? 0 : group.LastIndex; object groupNameKey = this.GetGroupNameKey(name, group); CollectionViewGroupInternal subgroupFromMap; if ((subgroupFromMap = group.GetSubgroupFromMap(groupNameKey)) != null && group.GroupBy.NamesMatch(subgroupFromMap.Name, name)) { group.LastIndex = group.Items[index] == subgroupFromMap ? index : 0; this.AddToSubgroups(item, lsi, subgroupFromMap, level + 1, loading); } else { for (int count = group.Items.Count; index < count; ++index) { CollectionViewGroupInternal viewGroupInternal = group.Items[index] as CollectionViewGroupInternal; if (viewGroupInternal != null && group.GroupBy.NamesMatch(viewGroupInternal.Name, name)) { group.LastIndex = index; group.AddSubgroupToMap(groupNameKey, viewGroupInternal); this.AddToSubgroups(item, lsi, viewGroupInternal, level + 1, loading); return; } } CollectionViewGroupInternal viewGroupInternal1 = new CollectionViewGroupInternal(name, group); this.InitializeGroup(viewGroupInternal1, group.GroupBy, level + 1); if (loading) { group.Add((object)viewGroupInternal1); group.LastIndex = index; } else { group.Insert((object)viewGroupInternal1, item, this.ActiveComparer); } group.AddSubgroupToMap(groupNameKey, viewGroupInternal1); this.AddToSubgroups(item, lsi, viewGroupInternal1, level + 1, loading); } }
internal void MoveWithinSubgroups(object item, LiveShapingItem lsi, IList list, int oldIndex, int newIndex) { if (lsi == null) { this.MoveWithinSubgroups(item, (CollectionViewGroupInternal)this, 0, list, oldIndex, newIndex); } else { CollectionViewGroupInternal parentGroup = lsi.ParentGroup; if (parentGroup != null) { this.MoveWithinSubgroup(item, parentGroup, list, oldIndex, newIndex); } else { foreach (CollectionViewGroupInternal group in lsi.ParentGroups) { this.MoveWithinSubgroup(item, group, list, oldIndex, newIndex); } } } }
// Token: 0x060026EA RID: 9962 RVA: 0x000B87EC File Offset: 0x000B69EC internal void InvalidateGroupItemPeersContainingRecentlyRealizedPeers(List <ItemAutomationPeer> recentlyRealizedPeers) { ItemsControl itemsControl = ItemsControl.ItemsControlFromItemContainer(base.Owner); if (itemsControl != null) { CollectionViewGroupInternal collectionViewGroupInternal = itemsControl.ItemContainerGenerator.ItemFromContainer(base.Owner) as CollectionViewGroupInternal; if (collectionViewGroupInternal != null) { for (int i = 0; i < recentlyRealizedPeers.Count; i++) { ItemAutomationPeer itemAutomationPeer = recentlyRealizedPeers[i]; object item = itemAutomationPeer.Item; if (collectionViewGroupInternal.LeafIndexOf(item) >= 0) { this.AncestorsInvalid = true; base.ChildrenValid = true; } } } } }
private object GetGroupNameKey(object name, CollectionViewGroupInternal group) { object obj = name; PropertyGroupDescription groupDescription = group.GroupBy as PropertyGroupDescription; if (groupDescription != null) { string str = name as string; if (str != null) { if (groupDescription.StringComparison == StringComparison.OrdinalIgnoreCase || groupDescription.StringComparison == StringComparison.InvariantCultureIgnoreCase) { str = str.ToUpperInvariant(); } else if (groupDescription.StringComparison == StringComparison.CurrentCultureIgnoreCase) { str = str.ToUpper(CultureInfo.CurrentCulture); } obj = (object)str; } } return(obj); }
/// <summary> /// Initialize the given group /// </summary> /// <param name="group">Group to initialize</param> /// <param name="level">The level of grouping</param> /// <param name="seedItem">The seed item to compare with to see where to insert</param> private void InitializeGroup(CollectionViewGroupInternal group, int level, object seedItem) { // set the group description for dividing the group into subgroups GroupDescription groupDescription = this.GetGroupDescription(group, level); group.GroupBy = groupDescription; // create subgroups for each of the explicit names ObservableCollection <object> explicitNames = (groupDescription != null) ? groupDescription.GroupNames : null; if (explicitNames != null) { for (int k = 0, n = explicitNames.Count; k < n; ++k) { CollectionViewGroupInternal subgroup = new CollectionViewGroupInternal(explicitNames[k], group); this.InitializeGroup(subgroup, level + 1, seedItem); group.Add(subgroup); } } group.LastIndex = 0; }
private void AddToSubgroups(object item, LiveShapingItem lsi, CollectionViewGroupInternal group, int level, bool loading) { object groupName = this.GetGroupName(item, group.GroupBy, level); if (groupName == CollectionViewGroupRoot.UseAsItemDirectly) { if (lsi != null) { lsi.AddParentGroup(group); } if (loading) { group.Add(item); } else { int index1 = group.Insert(item, item, this.ActiveComparer); int index2 = group.LeafIndexFromItem(item, index1); this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item, index2)); } } else { ICollection collection; if ((collection = groupName as ICollection) == null) { this.AddToSubgroup(item, lsi, group, level, groupName, loading); } else { foreach (object name in (IEnumerable)collection) { this.AddToSubgroup(item, lsi, group, level, name, loading); } } } }
/// <summary> /// Returns the index of the given item within the list of leaves governed /// by this group /// </summary> /// <param name="item">Item we are looking for</param> /// <returns>Number of items under that leaf</returns> internal int LeafIndexOf(object item) { int leaves = 0; // number of leaves we've passed over so far for (int k = 0, n = Items.Count; k < n; ++k) { CollectionViewGroupInternal subgroup = Items[k] as CollectionViewGroupInternal; if (subgroup != null) { int subgroupIndex = subgroup.LeafIndexOf(item); if (subgroupIndex < 0) { leaves += subgroup.ItemCount; // item not in this subgroup } else { return(leaves + subgroupIndex); // item is in this subgroup } } else { // current item is a leaf - compare it directly if (Object.Equals(item, Items[k])) { return(leaves); } else { leaves += 1; } } } // item not found return(-1); }
// move an item within the desired subgroup(s) of the given group private void MoveWithinSubgroups(object item, CollectionViewGroupInternal group, int level, IList list, int oldIndex, int newIndex) { object name = GetGroupName(item, group.GroupBy, level); ICollection nameList; if (name == UseAsItemDirectly) { // the item belongs to the group itself (not to any subgroups) MoveWithinSubgroup(item, group, list, oldIndex, newIndex); } else if ((nameList = name as ICollection) == null) { // the item belongs to one subgroup MoveWithinSubgroup(item, group, level, name, list, oldIndex, newIndex); } else { // the item belongs to multiple subgroups foreach (object o in nameList) { MoveWithinSubgroup(item, group, level, o, list, oldIndex, newIndex); } } }
private void MoveWithinSubgroups(object item, CollectionViewGroupInternal group, int level, IList list, int oldIndex, int newIndex) { object groupName = this.GetGroupName(item, group.GroupBy, level); if (groupName == CollectionViewGroupRoot.UseAsItemDirectly) { this.MoveWithinSubgroup(item, group, list, oldIndex, newIndex); } else { ICollection collection; if ((collection = groupName as ICollection) == null) { this.MoveWithinSubgroup(item, group, level, groupName, list, oldIndex, newIndex); } else { foreach (object name in (IEnumerable)collection) { this.MoveWithinSubgroup(item, group, level, name, list, oldIndex, newIndex); } } } }
private void MoveWithinSubgroup(object item, CollectionViewGroupInternal group, int level, object name, IList list, int oldIndex, int newIndex) { object groupNameKey = this.GetGroupNameKey(name, group); CollectionViewGroupInternal subgroupFromMap; if ((subgroupFromMap = group.GetSubgroupFromMap(groupNameKey)) != null && group.GroupBy.NamesMatch(subgroupFromMap.Name, name)) { this.MoveWithinSubgroups(item, subgroupFromMap, level + 1, list, oldIndex, newIndex); } else { int index = 0; for (int count = group.Items.Count; index < count; ++index) { CollectionViewGroupInternal viewGroupInternal = group.Items[index] as CollectionViewGroupInternal; if (viewGroupInternal != null && group.GroupBy.NamesMatch(viewGroupInternal.Name, name)) { group.AddSubgroupToMap(groupNameKey, viewGroupInternal); this.MoveWithinSubgroups(item, viewGroupInternal, level + 1, list, oldIndex, newIndex); break; } } } }
private bool RemoveFromGroupDirectly(CollectionViewGroupInternal group, object item) { int num = group.Remove(item, true); if (num >= 0) { this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(1, item, num)); return false; } return true; }
private void InitializeGroup(CollectionViewGroupInternal group, int level, object seedItem) { GroupDescription groupDescription = this.GetGroupDescription(group, level); group.GroupBy = groupDescription; ObservableCollection<object> observables = (groupDescription != null) ? groupDescription.get_GroupNames() : null; if (observables != null) { int num = 0; int count = observables.Count; while (num < count) { CollectionViewGroupInternal internal2 = new CollectionViewGroupInternal(observables[num], group); this.InitializeGroup(internal2, level + 1, seedItem); group.Add(internal2); num++; } } group.LastIndex = 0; }
// move an item and return true if it really moved. // Also translate the indices to "leaf" coordinates internal bool Move(object item, IList list, ref int oldIndex, ref int newIndex) { int oldIndexLocal = -1, newIndexLocal = -1; int localIndex = 0; int n = ProtectedItems.Count; // the input is in "full" coordinates. Find the corresponding local coordinates for (int fullIndex = 0; ; ++fullIndex) { if (fullIndex == oldIndex) { oldIndexLocal = localIndex; if (newIndexLocal >= 0) { break; } ++localIndex; } if (fullIndex == newIndex) { newIndexLocal = localIndex; if (oldIndexLocal >= 0) { --newIndexLocal; break; } ++fullIndex; ++oldIndex; } if (localIndex < n && ItemsControl.EqualsEx(ProtectedItems[localIndex], list[fullIndex])) { ++localIndex; } } // the move may be a no-op w.r.t. this group if (oldIndexLocal == newIndexLocal) { return(false); } // translate to "leaf" coordinates int low, high, lowLeafIndex, delta = 0; if (oldIndexLocal < newIndexLocal) { low = oldIndexLocal + 1; high = newIndexLocal + 1; lowLeafIndex = LeafIndexFromItem(null, oldIndexLocal); } else { low = newIndexLocal; high = oldIndexLocal; lowLeafIndex = LeafIndexFromItem(null, newIndexLocal); } for (int i = low; i < high; ++i) { CollectionViewGroupInternal subgroup = Items[i] as CollectionViewGroupInternal; delta += (subgroup == null) ? 1 : subgroup.ItemCount; } if (oldIndexLocal < newIndexLocal) { oldIndex = lowLeafIndex; newIndex = oldIndex + delta; } else { newIndex = lowLeafIndex; oldIndex = newIndex + delta; } // do the actual move ProtectedItems.Move(oldIndexLocal, newIndexLocal); return(true); }
// add a new child view in the paged collection (not necessarily a leaf) internal void AddView(CollectionViewGroupInternal view) { _views.Add(view); }
private bool RemoveFromSubgroups(object item, CollectionViewGroupInternal group, int level) { bool flag = false; object name = this.GetGroupName(item, group.GroupBy, level); if (name == UseAsItemDirectly) { return this.RemoveFromGroupDirectly(group, item); } ICollection is2 = name as ICollection; if (is2 == null) { if (this.RemoveFromSubgroup(item, group, level, name)) { flag = true; } return flag; } foreach (object obj3 in is2) { if (this.RemoveFromSubgroup(item, group, level, obj3)) { flag = true; } } return flag; }
public AbandonedGroupItem(LiveShapingItem lsi, CollectionViewGroupInternal group) { _lsi = lsi; _group = group; }
/// <summary> /// Remove an item from the desired subgroup(s) of the given group. /// </summary> /// <param name="item">Item to remove</param> /// <param name="group">Group to remove item from</param> /// <param name="level">The level of grouping</param> /// <returns>Return true if the item was not in one of the subgroups it was supposed to be.</returns> private bool RemoveFromSubgroups(object item, CollectionViewGroupInternal group, int level) { bool itemIsMissing = false; object name = this.GetGroupName(item, group.GroupBy, level); ICollection nameList; if (name == UseAsItemDirectly) { // the item belongs to the group itself (not to any subgroups) itemIsMissing = this.RemoveFromGroupDirectly(group, item); } else if ((nameList = name as ICollection) == null) { // the item belongs to one subgroup if (this.RemoveFromSubgroup(item, group, level, name)) { itemIsMissing = true; } } else { // the item belongs to multiple subgroups foreach (object o in nameList) { if (this.RemoveFromSubgroup(item, group, level, o)) { itemIsMissing = true; } } } return itemIsMissing; }
/// <summary> /// Add an item to the desired subgroup(s) of the given group /// </summary> /// <param name="item">Item to add</param> /// <param name="group">Group to add item to</param> /// <param name="level">The level of grouping</param> /// <param name="loading">Whether we are currently loading</param> /// <param name="insertedBefore">The item to insert this item before, /// or <c>null</c> if the item should be added at the end.</param> private void AddToSubgroups(object item, CollectionViewGroupInternal group, int level, bool loading, object insertedBefore) { object name = this.GetGroupName(item, group.GroupBy, level); ICollection nameList; if (name == UseAsItemDirectly) { // the item belongs to the group itself (not to any subgroups) if (loading) { group.Add(item); } else { int localIndex = -1; // If we were given an item to insert before, find its index // within the target group. If it's not in the group, we'll // get -1 back, which we'll translate into putting the item // at the end of the list. if (insertedBefore != null) { localIndex = group.LeafIndexOf(insertedBefore); } if (localIndex == -1) { localIndex = group.ItemCount; } group.Insert(item, localIndex); int index = group.LeafIndexFromItem(item, localIndex); this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item, index)); } } else if ((nameList = name as ICollection) == null) { // the item belongs to one subgroup this.AddToSubgroup(item, group, level, name, loading, insertedBefore); } else { // the item belongs to multiple subgroups foreach (object o in nameList) { this.AddToSubgroup(item, group, level, o, loading, insertedBefore); } } }
/// <summary> /// Remove an item from the direct children of a group. /// </summary> /// <param name="group">Group to remove item from</param> /// <param name="item">Item to remove</param> /// <returns>True if item could not be removed</returns> private bool RemoveFromGroupDirectly(CollectionViewGroupInternal group, object item) { int leafIndex = group.Remove(item, true); if (leafIndex >= 0) { this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item, leafIndex)); return false; } else { return true; } }
public LeafEnumerator(CollectionViewGroupInternal group) { _group = group; DoReset(); // don't call virtual Reset in ctor }
/// <summary> /// Maps the given name with the given subgroup /// </summary> internal void AddSubgroupToMap(object nameKey, CollectionViewGroupInternal subgroup) { Debug.Assert(subgroup != null); if (nameKey == null) { // use null name place holder. nameKey = _nullGroupNameKey; } if (_nameToGroupMap == null) { _nameToGroupMap = new Hashtable(); } // Add to the map. Use WeakReference to avoid memory leaks // in case some one calls ProtectedItems.Remove instead of // CollectionViewGroupInternal.Remove _nameToGroupMap[nameKey] = new WeakReference(subgroup); ScheduleMapCleanup(); }
private bool RemoveFromSubgroup(object item, CollectionViewGroupInternal group, int level, object name) { bool flag = false; int num = 0; int count = group.Items.Count; while (num < count) { CollectionViewGroupInternal internal2 = group.Items[num] as CollectionViewGroupInternal; if ((internal2 != null) && group.GroupBy.NamesMatch(internal2.Name, name)) { if (this.RemoveFromSubgroups(item, internal2, level + 1)) { flag = true; } return flag; } num++; } return true; }
internal void AddParentGroup(CollectionViewGroupInternal group) { object o = GetValue(ParentGroupsProperty); List<CollectionViewGroupInternal> list; if (o == null) { // no parents yet, store a singleton SetValue(ParentGroupsProperty, group); } else if ((list = o as List<CollectionViewGroupInternal>) == null) { // one parent, store a list list = new List<CollectionViewGroupInternal>(2); list.Add(o as CollectionViewGroupInternal); list.Add(group); SetValue(ParentGroupsProperty, list); } else { // many parents, add to the list list.Add(group); } }
// the item did not appear in one or more of the subgroups it // was supposed to. This can happen if the item's properties // change so that the group names we used to insert it are // different from the names used to remove it. If this happens, // remove the item the hard way. void RemoveItemFromSubgroupsByExhaustiveSearch(CollectionViewGroupInternal group, object item) { // try to remove the item from the direct children if (RemoveFromGroupDirectly(group, item)) { // if that didn't work, recurse into each subgroup // (loop runs backwards in case an entire group is deleted) for (int k=group.Items.Count-1; k >= 0; --k) { CollectionViewGroupInternal subgroup = group.Items[k] as CollectionViewGroupInternal; if (subgroup != null) { RemoveItemFromSubgroupsByExhaustiveSearch(subgroup, item); } } } else { // if the item was removed directly, we don't have to look at subgroups. // An item cannot appear both as a direct child and as a deeper descendant. } }
//------------------------------------------------------ // // Constructors // //------------------------------------------------------ /// <summary> /// Initializes a new instance of the CollectionViewGroupInternal class. /// </summary> /// <param name="name">Name of the CollectionViewGroupInternal</param> /// <param name="parent">Parent node of the CollectionViewGroup</param> internal CollectionViewGroupInternal(object name, CollectionViewGroupInternal parent) : base(name) { this._parentGroup = parent; }
/// <summary> /// Removes the given subgroup from the name to group map. /// </summary> private void RemoveSubgroupFromMap(CollectionViewGroupInternal subgroup) { Debug.Assert(subgroup != null); if (_nameToGroupMap == null) { return; } object keyToBeRemoved = null; // Search for the subgroup in the map. foreach (object key in _nameToGroupMap.Keys) { WeakReference weakRef = _nameToGroupMap[key] as WeakReference; if (weakRef != null && weakRef.Target == subgroup) { keyToBeRemoved = key; break; } } if (keyToBeRemoved != null) { _nameToGroupMap.Remove(keyToBeRemoved); } ScheduleMapCleanup(); }
private void AddToSubgroup(object item, CollectionViewGroupInternal group, int level, object name, bool loading) { int index = 0; for (int count = group.Items.Count; index < count; ++index) { CollectionViewGroupInternal group1 = group.Items[index] as CollectionViewGroupInternal; if (group1 != null && group.GroupBy.NamesMatch(group1.Name, name)) { group.LastIndex = index; this.AddToSubgroups(item, group1, level + 1, loading); return; } } CollectionViewGroupInternal group2 = new CollectionViewGroupInternal(name, group); this.InitializeGroup(group2, level + 1); if (loading) { group.Add((object)group2); group.LastIndex = index; } else { group.Insert((object)group2, item, this.ActiveComparer); } this.AddToSubgroups(item, group2, level + 1, loading); }
//------------------------------------------------------ // // Private Methods // //------------------------------------------------------ /// <summary> /// Add an item to the subgroup with the given name /// </summary> /// <param name="item">Item to add</param> /// <param name="group">Group to add item to</param> /// <param name="level">The level of grouping.</param> /// <param name="name">Name of subgroup to add to</param> /// <param name="loading">Whether we are currently loading</param> /// <param name="insertedBefore">The item to insert this item before, /// or <c>null</c> if the item should be added at the end.</param> private void AddToSubgroup(object item, CollectionViewGroupInternal group, int level, object name, bool loading, object insertedBefore) { CollectionViewGroupInternal subgroup; int index = (this._isDataInGroupOrder) ? group.LastIndex : 0; // find the desired subgroup for (int n = group.Items.Count; index < n; ++index) { subgroup = group.Items[index] as CollectionViewGroupInternal; if (subgroup == null) { continue; // skip children that are not groups } if (group.GroupBy.NamesMatch(subgroup.Name, name)) { group.LastIndex = index; this.AddToSubgroups(item, subgroup, level + 1, loading, insertedBefore); return; } } // the item didn't match any subgroups. Create a new subgroup and add the item. subgroup = new CollectionViewGroupInternal(name, group); this.InitializeGroup(subgroup, level + 1, item); if (loading) { group.Add(subgroup); group.LastIndex = index; } else { if (insertedBefore != null && group.ItemCount > 0) { index = 0; // If we were given an item to insert before, find its index // within the target group. If it's not in the group, we'll // get -1 back, which we'll translate into putting the item // at the end of the list. int itemIndex = group.LeafIndexOf(insertedBefore); if (itemIndex == -1) { index = group.ItemCount; } else { // But if the item to be inserted before is within this // group, then we need to find the correct group position // for the insert. Iterate through the groups, finding // the correct insert position. CollectionViewGroupInternal nextGroup = ((CollectionViewGroupInternal)group.Items[index]); while (itemIndex >= nextGroup.ItemCount) { itemIndex -= nextGroup.ItemCount; // Increment the index and set the next group nextGroup = ((CollectionViewGroupInternal)group.Items[++index]); } } } group.Insert(subgroup, index); } this.AddToSubgroups(item, subgroup, level + 1, loading, insertedBefore); }
private void AddToSubgroups(object item, CollectionViewGroupInternal group, int level, bool loading) { object groupName = this.GetGroupName(item, group.GroupBy, level); if (groupName == CollectionViewGroupRoot.UseAsItemDirectly) { if (loading) { group.Add(item); } else { int index1 = group.Insert(item, item, this.ActiveComparer); int index2 = group.LeafIndexFromItem(item, index1); this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item, index2)); } } else { ICollection collection; if ((collection = groupName as ICollection) == null) { this.AddToSubgroup(item, group, level, groupName, loading); } else { foreach (object name in (IEnumerable)collection) { this.AddToSubgroup(item, group, level, name, loading); } } } }
/// <summary> /// Initialize the given group /// </summary> /// <param name="group">Group to initialize</param> /// <param name="level">The level of grouping</param> /// <param name="seedItem">The seed item to compare with to see where to insert</param> private void InitializeGroup(CollectionViewGroupInternal group, int level, object seedItem) { // set the group description for dividing the group into subgroups GroupDescription groupDescription = this.GetGroupDescription(group, level); group.GroupBy = groupDescription; // create subgroups for each of the explicit names ObservableCollection<object> explicitNames = (groupDescription != null) ? groupDescription.GroupNames : null; if (explicitNames != null) { for (int k = 0, n = explicitNames.Count; k < n; ++k) { CollectionViewGroupInternal subgroup = new CollectionViewGroupInternal(explicitNames[k], group); this.InitializeGroup(subgroup, level + 1, seedItem); group.Add(subgroup); } } group.LastIndex = 0; }
private void InitializeGroup(CollectionViewGroupInternal group, int level) { GroupDescription groupDescription = level < this.GroupDescriptions.Count ? this.GroupDescriptions[level] : (GroupDescription)null; group.GroupBy = groupDescription; ObservableCollection<object> observableCollection = groupDescription != null ? groupDescription.GroupNames : (ObservableCollection<object>)null; if (observableCollection != null) { int index = 0; for (int count = observableCollection.Count; index < count; ++index) { CollectionViewGroupInternal group1 = new CollectionViewGroupInternal(observableCollection[index], group); this.InitializeGroup(group1, level + 1); group.Add((object)group1); } } group.LastIndex = 0; }
/// <summary> /// Remove an item from the subgroup with the given name. /// </summary> /// <param name="item">Item to remove</param> /// <param name="group">Group to remove item from</param> /// <param name="level">The level of grouping</param> /// <param name="name">Name of item to remove</param> /// <returns>Return true if the item was not in one of the subgroups it was supposed to be.</returns> private bool RemoveFromSubgroup(object item, CollectionViewGroupInternal group, int level, object name) { bool itemIsMissing = false; CollectionViewGroupInternal subgroup; // find the desired subgroup for (int index = 0, n = group.Items.Count; index < n; ++index) { subgroup = group.Items[index] as CollectionViewGroupInternal; if (subgroup == null) { continue; // skip children that are not groups } if (group.GroupBy.NamesMatch(subgroup.Name, name)) { if (this.RemoveFromSubgroups(item, subgroup, level + 1)) { itemIsMissing = true; } return itemIsMissing; } } // the item didn't match any subgroups. It should have. return true; }
private bool RemoveFromSubgroup(object item, CollectionViewGroupInternal group, int level, object name) { bool flag = false; int index = 0; for (int count = group.Items.Count; index < count; ++index) { CollectionViewGroupInternal group1 = group.Items[index] as CollectionViewGroupInternal; if (group1 != null && group.GroupBy.NamesMatch(group1.Name, name)) { if (this.RemoveFromSubgroups(item, group1, level + 1)) { flag = true; } return flag; } } return true; }
private bool RemoveFromSubgroups(object item, CollectionViewGroupInternal group, int level) { bool flag = false; object groupName = this.GetGroupName(item, group.GroupBy, level); if (groupName == CollectionViewGroupRoot.UseAsItemDirectly) { flag = this.RemoveFromGroupDirectly(group, item); } else { ICollection collection; if ((collection = groupName as ICollection) == null) { if (this.RemoveFromSubgroup(item, group, level, groupName)) { flag = true; } } else { foreach (object name in (IEnumerable)collection) { if (this.RemoveFromSubgroup(item, group, level, name)) { flag = true; } } } } return flag; }
internal void RemoveParentGroup(CollectionViewGroupInternal group) { object o = GetValue(ParentGroupsProperty); List<CollectionViewGroupInternal> list = o as List<CollectionViewGroupInternal>; if (list == null) { // one parent, remove it if (o == group) { ClearValue(ParentGroupsProperty); } } else { // many parents, remove from the list list.Remove(group); if (list.Count == 1) { // collapse a singleton list SetValue(ParentGroupsProperty, list[0]); } } }
private int _version; // parent group's version at ctor /// <summary> /// Initializes a new instance of the LeafEnumerator class. /// </summary> /// <param name="group">CollectionViewGroupInternal that uses the enumerator</param> public LeafEnumerator(CollectionViewGroupInternal group) { this._group = group; this.DoReset(); // don't call virtual Reset in ctor }
private void RemoveItemFromSubgroupsByExhaustiveSearch(CollectionViewGroupInternal group, object item) { if (this.RemoveFromGroupDirectly(group, item)) { for (int i = group.Items.Count - 1; i >= 0; i--) { CollectionViewGroupInternal internal2 = group.Items[i] as CollectionViewGroupInternal; if (internal2 != null) { this.RemoveItemFromSubgroupsByExhaustiveSearch(internal2, item); } } } }
//------------------------------------------------------ // // Constructors // //------------------------------------------------------ /// <summary> /// Initializes a new instance of the <see cref="CollectionViewGroupInternal"/> class. /// </summary> /// <param name="name">Name of the CollectionViewGroupInternal</param> /// <param name="parent">Parent node of the CollectionViewGroup</param> internal CollectionViewGroupInternal(object name, CollectionViewGroupInternal parent) : base(name) { this._parentGroup = parent; }
// remove an item from the subgroup with the given name. // Return true if the item was not in one of the subgroups it was supposed to be. bool RemoveFromSubgroup(object item, CollectionViewGroupInternal group, int level, object name) { CollectionViewGroupInternal subgroup; // find the desired subgroup using the map object groupNameKey = GetGroupNameKey(name, group); if (((subgroup = group.GetSubgroupFromMap(groupNameKey) as CollectionViewGroupInternal) != null) && group.GroupBy.NamesMatch(subgroup.Name, name)) { // Recursively call the RemoveFromSubgroups method on subgroup. return RemoveFromSubgroups(item, subgroup, level + 1); } // find the desired subgroup using linear search for (int index=0, n=group.Items.Count; index < n; ++index) { subgroup = group.Items[index] as CollectionViewGroupInternal; if (subgroup == null) continue; // skip children that are not groups if (group.GroupBy.NamesMatch(subgroup.Name, name)) { // Recursively call the RemoveFromSubgroups method on subgroup. return RemoveFromSubgroups(item, subgroup, level + 1); } } // the item didn't match any subgroups. It should have. return true; }