// Token: 0x06008D89 RID: 36233 RVA: 0x002599D8 File Offset: 0x00257BD8 public void Dispose() { if (this._toRemove != null) { foreach (CollectionViewGroupInternal collectionViewGroupInternal in this._toRemove) { CollectionViewGroupInternal parent = collectionViewGroupInternal.Parent; if (parent != null && !collectionViewGroupInternal.IsExplicit) { parent.Remove(collectionViewGroupInternal, false); } } } }
// Token: 0x060073DB RID: 29659 RVA: 0x002129AC File Offset: 0x00210BAC private void RemoveItemFromSubgroupsByExhaustiveSearch(CollectionViewGroupInternal group, object item) { if (this.RemoveFromGroupDirectly(group, item)) { for (int i = group.Items.Count - 1; i >= 0; i--) { CollectionViewGroupInternal collectionViewGroupInternal = group.Items[i] as CollectionViewGroupInternal; if (collectionViewGroupInternal != null) { this.RemoveItemFromSubgroupsByExhaustiveSearch(collectionViewGroupInternal, item); } } } }
// remove an item from the direct children of a group. // Return true if this couldn't be done. bool RemoveFromGroupDirectly(CollectionViewGroupInternal group, object item) { int leafIndex = group.Remove(item, true); if (leafIndex >= 0) { OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item, leafIndex)); return(false); } else { return(true); } }
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); } } }
/// <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(); }
// Token: 0x060073CA RID: 29642 RVA: 0x00211F70 File Offset: 0x00210170 internal void MoveWithinSubgroups(object item, LiveShapingItem lsi, IList list, int oldIndex, int newIndex) { if (lsi == null) { this.MoveWithinSubgroups(item, this, 0, list, oldIndex, newIndex); return; } CollectionViewGroupInternal parentGroup = lsi.ParentGroup; if (parentGroup != null) { this.MoveWithinSubgroup(item, parentGroup, list, oldIndex, newIndex); return; } foreach (CollectionViewGroupInternal group in lsi.ParentGroups) { this.MoveWithinSubgroup(item, group, list, oldIndex, newIndex); } }
public void Dispose() { if (_toRemove != null) { foreach (CollectionViewGroupInternal group in _toRemove) { CollectionViewGroupInternal parent = group.Parent; if (parent != null) { // remove the subgroup unless it is one of the explicit groups if (!group.IsExplicit) { parent.Remove(group, false); } } } } }
// move an item within the subgroup with the given name void MoveWithinSubgroup(object item, CollectionViewGroupInternal group, int level, object name, IList list, int oldIndex, int newIndex) { CollectionViewGroupInternal subgroup; // find the desired subgroup using the map object groupNameKey = GetGroupNameKey(name, group); if (((subgroup = group.GetSubgroupFromMap(groupNameKey)) != null) && group.GroupBy.NamesMatch(subgroup.Name, name)) { // Recursively call the MoveWithinSubgroups method on subgroup. MoveWithinSubgroups(item, subgroup, level + 1, list, oldIndex, newIndex); return; } // 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)) { // Update the name to subgroup map on the group. group.AddSubgroupToMap(groupNameKey, subgroup); // Recursively call the MoveWithinSubgroups method on subgroup. MoveWithinSubgroups(item, subgroup, level + 1, list, oldIndex, newIndex); return; } } // the item didn't match any subgroups. Something is wrong. // This could happen if the app changes the item's group name (by changing // properties that the name depends on) without notification. // We don't support this - the Move is just a no-op. But assert (in // debug builds) to help diagnose the problem if it arises. Debug.Assert(false, "Failed to find item in expected subgroup after Move"); }
// Token: 0x060073D4 RID: 29652 RVA: 0x00212690 File Offset: 0x00210890 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); return; } ICollection collection; if ((collection = (groupName as ICollection)) == null) { this.MoveWithinSubgroup(item, group, level, groupName, list, oldIndex, newIndex); return; } foreach (object name in collection) { this.MoveWithinSubgroup(item, group, level, name, list, oldIndex, newIndex); } }
// Token: 0x060073D0 RID: 29648 RVA: 0x002123D8 File Offset: 0x002105D8 private void InitializeGroup(CollectionViewGroupInternal group, GroupDescription parentDescription, int level) { GroupDescription groupDescription = this.GetGroupDescription(group, parentDescription, level); group.GroupBy = groupDescription; ObservableCollection <object> observableCollection = (groupDescription != null) ? groupDescription.GroupNames : null; if (observableCollection != null) { int i = 0; int count = observableCollection.Count; while (i < count) { CollectionViewGroupInternal collectionViewGroupInternal = new CollectionViewGroupInternal(observableCollection[i], group, true); this.InitializeGroup(collectionViewGroupInternal, groupDescription, level + 1); group.Add(collectionViewGroupInternal); i++; } } group.LastIndex = 0; }
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]); } } }
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); } }
// Token: 0x060075A0 RID: 30112 RVA: 0x00219530 File Offset: 0x00217730 internal void AddParentGroup(CollectionViewGroupInternal group) { object value = base.GetValue(LiveShapingItem.ParentGroupsProperty); if (value == null) { base.SetValue(LiveShapingItem.ParentGroupsProperty, group); return; } List <CollectionViewGroupInternal> list; if ((list = (value as List <CollectionViewGroupInternal>)) == null) { list = new List <CollectionViewGroupInternal>(2); list.Add(value as CollectionViewGroupInternal); list.Add(group); base.SetValue(LiveShapingItem.ParentGroupsProperty, list); return; } list.Add(group); }
// Token: 0x060073AF RID: 29615 RVA: 0x00211B64 File Offset: 0x0020FD64 protected void ChangeCounts(object item, int delta) { bool flag = !(item is CollectionViewGroup); using (CollectionViewGroupInternal.EmptyGroupRemover emptyGroupRemover = CollectionViewGroupInternal.EmptyGroupRemover.Create(flag && delta < 0)) { for (CollectionViewGroupInternal collectionViewGroupInternal = this; collectionViewGroupInternal != null; collectionViewGroupInternal = collectionViewGroupInternal._parentGroup) { collectionViewGroupInternal.FullCount += delta; if (flag) { collectionViewGroupInternal.ProtectedItemCount += delta; if (collectionViewGroupInternal.ProtectedItemCount == 0) { emptyGroupRemover.RemoveEmptyGroup(collectionViewGroupInternal); } } } } this._version++; }
// Token: 0x060073A2 RID: 29602 RVA: 0x002116EC File Offset: 0x0020F8EC internal int LeafIndexFromItem(object item, int index) { int num = 0; CollectionViewGroupInternal collectionViewGroupInternal = this; while (collectionViewGroupInternal != null) { int num2 = 0; int count = collectionViewGroupInternal.Items.Count; while (num2 < count && (index >= 0 || !ItemsControl.EqualsEx(item, collectionViewGroupInternal.Items[num2])) && index != num2) { CollectionViewGroupInternal collectionViewGroupInternal2 = collectionViewGroupInternal.Items[num2] as CollectionViewGroupInternal; num += ((collectionViewGroupInternal2 == null) ? 1 : collectionViewGroupInternal2.ItemCount); num2++; } item = collectionViewGroupInternal; collectionViewGroupInternal = collectionViewGroupInternal.Parent; index = -1; } return(num); }
// Token: 0x060073D3 RID: 29651 RVA: 0x00212564 File Offset: 0x00210764 private void AddToSubgroup(object item, LiveShapingItem lsi, CollectionViewGroupInternal group, int level, object name, bool loading) { int i = (loading && this.IsDataInGroupOrder) ? group.LastIndex : 0; object groupNameKey = this.GetGroupNameKey(name, group); CollectionViewGroupInternal collectionViewGroupInternal; if ((collectionViewGroupInternal = group.GetSubgroupFromMap(groupNameKey)) != null && group.GroupBy.NamesMatch(collectionViewGroupInternal.Name, name)) { group.LastIndex = ((group.Items[i] == collectionViewGroupInternal) ? i : 0); this.AddToSubgroups(item, lsi, collectionViewGroupInternal, level + 1, loading); return; } int count = group.Items.Count; while (i < count) { collectionViewGroupInternal = (group.Items[i] as CollectionViewGroupInternal); if (collectionViewGroupInternal != null && group.GroupBy.NamesMatch(collectionViewGroupInternal.Name, name)) { group.LastIndex = i; group.AddSubgroupToMap(groupNameKey, collectionViewGroupInternal); this.AddToSubgroups(item, lsi, collectionViewGroupInternal, level + 1, loading); return; } i++; } collectionViewGroupInternal = new CollectionViewGroupInternal(name, group, false); this.InitializeGroup(collectionViewGroupInternal, group.GroupBy, level + 1); if (loading) { group.Add(collectionViewGroupInternal); group.LastIndex = i; } else { group.Insert(collectionViewGroupInternal, item, this.ActiveComparer); } group.AddSubgroupToMap(groupNameKey, collectionViewGroupInternal); this.AddToSubgroups(item, lsi, collectionViewGroupInternal, level + 1, loading); }
//------------------------------------------------------ // // Private methods // //------------------------------------------------------ protected void ChangeCounts(object item, int delta) { bool changeLeafCount = !(item is CollectionViewGroup); for (CollectionViewGroupInternal group = this; group != null; group = group._parentGroup) { group.FullCount += delta; if (changeLeafCount) { group.ProtectedItemCount += delta; if (group.ProtectedItemCount == 0) { RemoveEmptyGroup(group); } } } unchecked { ++_version; } // this invalidates enumerators }
// Token: 0x060075A1 RID: 30113 RVA: 0x00219594 File Offset: 0x00217794 internal void RemoveParentGroup(CollectionViewGroupInternal group) { object value = base.GetValue(LiveShapingItem.ParentGroupsProperty); List <CollectionViewGroupInternal> list = value as List <CollectionViewGroupInternal>; if (list == null) { if (value == group) { base.ClearValue(LiveShapingItem.ParentGroupsProperty); return; } } else { list.Remove(group); if (list.Count == 1) { base.SetValue(LiveShapingItem.ParentGroupsProperty, list[0]); } } }
// 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. } }
bool IEnumerator.MoveNext() { // check for invalidated enumerator if (_group._version != _version) { throw new InvalidOperationException(); } // move forward to the next leaf while (_subEnum == null || !_subEnum.MoveNext()) { // done with the current top-level item. Move to the next one. ++_index; if (_index >= _group.Items.Count) { return(false); } CollectionViewGroupInternal subgroup = _group.Items[_index] as CollectionViewGroupInternal; if (subgroup == null) { // current item is a leaf - it's the new Current _current = _group.Items[_index]; _subEnum = null; return(true); } else { // current item is a subgroup - get its enumerator _subEnum = subgroup.GetLeafEnumerator(); } } // the loop terminates only when we have a subgroup enumerator // positioned at the new Current item _current = _subEnum.Current; return(true); }
// add an item to the desired subgroup(s) of the given group void AddToSubgroups(object item, LiveShapingItem lsi, CollectionViewGroupInternal group, int level, bool loading) { object name = GetGroupName(item, group.GroupBy, level); ICollection nameList; if (name == UseAsItemDirectly) { // the item belongs to the group itself (not to any subgroups) if (lsi != null) { lsi.AddParentGroup(group); } if (loading) { group.Add(item); } else { int localIndex = group.Insert(item, item, ActiveComparer); int index = group.LeafIndexFromItem(item, localIndex); OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item, index)); } } else if ((nameList = name as ICollection) == null) { // the item belongs to one subgroup AddToSubgroup(item, lsi, group, level, name, loading); } else { // the item belongs to multiple subgroups foreach (object o in nameList) { AddToSubgroup(item, lsi, group, level, o, loading); } } }
// Token: 0x060073A6 RID: 29606 RVA: 0x00211844 File Offset: 0x0020FA44 protected virtual int FindIndex(object item, object seed, IComparer comparer, int low, int high) { int i; if (this._groupComparer == null) { if (comparer != null) { CollectionViewGroupInternal.IListComparer listComparer = comparer as CollectionViewGroupInternal.IListComparer; if (listComparer != null) { listComparer.Reset(); } for (i = low; i < high; i++) { CollectionViewGroupInternal collectionViewGroupInternal = base.ProtectedItems[i] as CollectionViewGroupInternal; object obj = (collectionViewGroupInternal != null) ? collectionViewGroupInternal.SeedItem : base.ProtectedItems[i]; if (obj != DependencyProperty.UnsetValue && comparer.Compare(seed, obj) < 0) { break; } } } else { i = high; } } else { i = low; while (i < high && this._groupComparer.Compare(item, base.ProtectedItems[i]) >= 0) { i++; } } return(i); }
// Token: 0x060073D9 RID: 29657 RVA: 0x002128EC File Offset: 0x00210AEC private bool RemoveFromSubgroup(object item, CollectionViewGroupInternal group, int level, object name) { object groupNameKey = this.GetGroupNameKey(name, group); CollectionViewGroupInternal collectionViewGroupInternal; if ((collectionViewGroupInternal = group.GetSubgroupFromMap(groupNameKey)) != null && group.GroupBy.NamesMatch(collectionViewGroupInternal.Name, name)) { return(this.RemoveFromSubgroups(item, collectionViewGroupInternal, level + 1)); } int i = 0; int count = group.Items.Count; while (i < count) { collectionViewGroupInternal = (group.Items[i] as CollectionViewGroupInternal); if (collectionViewGroupInternal != null && group.GroupBy.NamesMatch(collectionViewGroupInternal.Name, name)) { return(this.RemoveFromSubgroups(item, collectionViewGroupInternal, level + 1)); } i++; } return(true); }
// Token: 0x060073D7 RID: 29655 RVA: 0x002127F4 File Offset: 0x002109F4 private object GetGroupNameKey(object name, CollectionViewGroupInternal group) { object result = name; PropertyGroupDescription propertyGroupDescription = group.GroupBy as PropertyGroupDescription; if (propertyGroupDescription != null) { string text = name as string; if (text != null) { if (propertyGroupDescription.StringComparison == StringComparison.OrdinalIgnoreCase || propertyGroupDescription.StringComparison == StringComparison.InvariantCultureIgnoreCase) { text = text.ToUpperInvariant(); } else if (propertyGroupDescription.StringComparison == StringComparison.CurrentCultureIgnoreCase) { text = text.ToUpper(CultureInfo.CurrentCulture); } result = text; } } return(result); }
// Initialize the given group void InitializeGroup(CollectionViewGroupInternal group, GroupDescription parentDescription, int level) { // set the group description for dividing the group into subgroups GroupDescription groupDescription = GetGroupDescription(group, parentDescription, 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, isExplicit: true); InitializeGroup(subgroup, groupDescription, level + 1); group.Add(subgroup); } } group.LastIndex = 0; }
// Token: 0x060073AA RID: 29610 RVA: 0x00211A4C File Offset: 0x0020FC4C private void RemoveSubgroupFromMap(CollectionViewGroupInternal subgroup) { if (this._nameToGroupMap == null) { return; } object obj = null; foreach (object obj2 in this._nameToGroupMap.Keys) { WeakReference weakReference = this._nameToGroupMap[obj2] as WeakReference; if (weakReference != null && weakReference.Target == subgroup) { obj = obj2; break; } } if (obj != null) { this._nameToGroupMap.Remove(obj); } this.ScheduleMapCleanup(); }
/// <summary> /// Helper method to normalize the group name. /// Normalization happens only if the cases where /// PropertyGroupDescriptions are used with /// case insensitive comparisons. /// </summary> object GetGroupNameKey(object name, CollectionViewGroupInternal group) { object groupNameKey = name; PropertyGroupDescription pgd = group.GroupBy as PropertyGroupDescription; if (pgd != null) { string nameStr = name as string; if (nameStr != null) { if (pgd.StringComparison == StringComparison.OrdinalIgnoreCase || pgd.StringComparison == StringComparison.InvariantCultureIgnoreCase) { nameStr = nameStr.ToUpperInvariant(); } else if (pgd.StringComparison == StringComparison.CurrentCultureIgnoreCase) { nameStr = nameStr.ToUpper(CultureInfo.CurrentCulture); } groupNameKey = nameStr; } } return(groupNameKey); }
// move an item within the desired subgroup(s) of the given group 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); } } }
// return the index of the given item within the list of leaves governed // by this group 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 (System.Windows.Controls.ItemsControl.EqualsEx(item, Items[k])) { return(leaves); } else { leaves += 1; } } } // item not found return(-1); }
protected virtual int FindIndex(object item, object seed, IComparer comparer, int low, int high) { int index; if (comparer != null) { IListComparer ilc = comparer as IListComparer; if (ilc != 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. ilc.Reset(); } for (index = low; index < high; ++index) { CollectionViewGroupInternal subgroup = ProtectedItems[index] as CollectionViewGroupInternal; object seed1 = (subgroup != null) ? subgroup.SeedItem : ProtectedItems[index]; if (seed1 == DependencyProperty.UnsetValue) { continue; } if (comparer.Compare(seed, seed1) < 0) { break; } } } else { index = high; } return(index); }