// An item was inserted into the collection. Update the groups. void AddItemToGroups(object item, LiveShapingItem lsi) { if (IsAddingNew && item == _newItem) { int index; switch (NewItemPlaceholderPosition) { case NewItemPlaceholderPosition.None: default: index = _group.Items.Count; break; case NewItemPlaceholderPosition.AtBeginning: index = 1; break; case NewItemPlaceholderPosition.AtEnd: index = _group.Items.Count - 1; break; } _group.InsertSpecialItem(index, item, false /*loading*/); } else { _group.AddToSubgroups(item, lsi, false /*loading*/); } }
// An item has moved. Update the groups void MoveItemWithinGroups(object item, LiveShapingItem lsi, int oldIndex, int newIndex) { _group.MoveWithinSubgroups(item, lsi, InternalList, oldIndex, newIndex); }
// add an item to the subgroup with the given name void AddToSubgroup(object item, LiveShapingItem lsi, CollectionViewGroupInternal group, int level, object name, bool loading) { CollectionViewGroupInternal subgroup; int index = (loading && IsDataInGroupOrder) ? group.LastIndex : 0; // 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)) { // Try best to set the LastIndex. If not possible reset it to 0. group.LastIndex = (group.Items[index] == subgroup ? index : 0); // Recursively call the AddToSubgroups method on subgroup. AddToSubgroups(item, lsi, subgroup, level + 1, loading); return; } // find the desired subgroup using linear search 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; // Update the name to subgroup map on the group. group.AddSubgroupToMap(groupNameKey, subgroup); // Recursively call the AddToSubgroups method on subgroup. AddToSubgroups(item, lsi, 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); InitializeGroup(subgroup, group.GroupBy, level+1); if (loading) { group.Add(subgroup); group.LastIndex = index; } else { group.Insert(subgroup, item, ActiveComparer); } // Update the name to subgroup map on the group. group.AddSubgroupToMap(groupNameKey, subgroup); // Recursively call the AddToSubgroups method on subgroup. AddToSubgroups(item, lsi, subgroup, level+1, loading); }
public AbandonedGroupItem(LiveShapingItem lsi, CollectionViewGroupInternal group) { _lsi = lsi; _group = group; }
GroupTreeNode BuildGroupTree(LiveShapingItem lsi) { CollectionViewGroupInternal parentGroup = lsi.ParentGroup; GroupTreeNode node; if (parentGroup != null) { // 90% case - item belongs to only one group. Construct tree // the fast way node = new GroupTreeNode() { Group = parentGroup, ContainsItemDirectly = true }; for (;;) { CollectionViewGroupInternal group = parentGroup; parentGroup = group.Parent; if (parentGroup == null) break; GroupTreeNode parentNode = new GroupTreeNode() { Group = parentGroup, FirstChild = node }; node = parentNode; } return node; } else { // item belongs to multiple groups ("categories"). Construct tree // the slow way. List<CollectionViewGroupInternal> parentGroups = lsi.ParentGroups; List<GroupTreeNode> list = new List<GroupTreeNode>(parentGroups.Count + 1); GroupTreeNode root = null; // initialize the list with a node for each direct parent group foreach (CollectionViewGroupInternal group in parentGroups) { node = new GroupTreeNode() { Group = group, ContainsItemDirectly = true }; list.Add(node); } // add each node in the list to the tree for (int index = 0; index < list.Count; ++index) { node = list[index]; parentGroup = node.Group.Parent; GroupTreeNode parentNode = null; // special case for the root if (parentGroup == null) { root = node; continue; } // search for an existing parent node for (int k=list.Count-1; k>=0; --k) { if (list[k].Group == parentGroup) { parentNode = list[k]; break; } } if (parentNode == null) { // no existing parent node - create one now parentNode = new GroupTreeNode() { Group = parentGroup, FirstChild = node }; list.Add(parentNode); } else { // add node to existing parent node.Sibling = parentNode.FirstChild; parentNode.FirstChild = node; } } return root; } }
// 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); } } }
// for the given item, check its grouping, add it to groups it has newly joined, // and record groups it has newly left in the delete-list internal void RestoreGrouping(LiveShapingItem lsi, List<AbandonedGroupItem> deleteList) { GroupTreeNode root = BuildGroupTree(lsi); root.ContainsItem = true; RestoreGrouping(lsi, root, 0, deleteList); }
void RestoreGrouping(LiveShapingItem lsi, GroupTreeNode node, int level, List<AbandonedGroupItem> deleteList) { if (node.ContainsItem) { // item belongs to this group - check subgroups object name = GetGroupName(lsi.Item, node.Group.GroupBy, level); if (name != UseAsItemDirectly) { ICollection ic = name as ICollection; ArrayList names = (ic == null) ? null : new ArrayList(ic); // find subgroups whose names still match for (GroupTreeNode child = node.FirstChild; child != null; child = child.Sibling) { if (names == null) { if (Object.Equals(name, child.Group.Name)) { child.ContainsItem = true; name = DependencyProperty.UnsetValue; // name is 'seen' break; } } else { if (names.Contains(child.Group.Name)) { child.ContainsItem = true; names.Remove(child.Group.Name); } } } // for names that don't match, add the item to the new subgroup if (names == null) { if (name != DependencyProperty.UnsetValue) { AddToSubgroup(lsi.Item, lsi, node.Group, level, name, false); } } else { foreach (object o in names) { AddToSubgroup(lsi.Item, lsi, node.Group, level, o, false); } } } } else { // item doesn't belong to this group - if it used to belong directly, // mark it for deletion if (node.ContainsItemDirectly) { deleteList.Add(new AbandonedGroupItem(lsi, node.Group)); } } // recursively handle children for (GroupTreeNode child = node.FirstChild; child != null; child = child.Sibling) { RestoreGrouping(lsi, child, level+1, deleteList); } }
internal void AddToSubgroups(object item, LiveShapingItem lsi, bool loading) { AddToSubgroups(item, lsi, this, 0, loading); }
internal void MoveWithinSubgroups(object item, LiveShapingItem lsi, IList list, int oldIndex, int newIndex) { if (lsi == null) { // recursively descend through the groups, moving the item within // groups it belongs to MoveWithinSubgroups(item, this, 0, list, oldIndex, newIndex); } else { // when live shaping is in effect, lsi records which groups the item // belongs to. Move the item within those groups CollectionViewGroupInternal parentGroup = lsi.ParentGroup; if (parentGroup != null) { // 90% case - item belongs to a single group MoveWithinSubgroup(item, parentGroup, list, oldIndex, newIndex); } else { // 10% case - item belongs to many groups foreach (CollectionViewGroupInternal group in lsi.ParentGroups) { MoveWithinSubgroup(item, group, list, oldIndex, newIndex); } } } }
// Remove an item from the filtered list internal void RemoveFilteredItem(LiveShapingItem lsi) { _filterRoot.RemoveAt(_filterRoot.IndexOf(lsi)); ClearItem(lsi); }
// Add an item to the filtered list internal void AddFilteredItem(LiveShapingItem lsi) { InitializeItem(lsi, lsi.Item, true, false); lsi.FailsFilter = true; _filterRoot.Insert(_filterRoot.Count, lsi); }
// Token: 0x060073CE RID: 29646 RVA: 0x002121F4 File Offset: 0x002103F4 private CollectionViewGroupRoot.GroupTreeNode BuildGroupTree(LiveShapingItem lsi) { CollectionViewGroupInternal collectionViewGroupInternal = lsi.ParentGroup; if (collectionViewGroupInternal != null) { CollectionViewGroupRoot.GroupTreeNode groupTreeNode = new CollectionViewGroupRoot.GroupTreeNode { Group = collectionViewGroupInternal, ContainsItemDirectly = true }; for (;;) { CollectionViewGroupInternal collectionViewGroupInternal2 = collectionViewGroupInternal; collectionViewGroupInternal = collectionViewGroupInternal2.Parent; if (collectionViewGroupInternal == null) { break; } CollectionViewGroupRoot.GroupTreeNode groupTreeNode2 = new CollectionViewGroupRoot.GroupTreeNode { Group = collectionViewGroupInternal, FirstChild = groupTreeNode }; groupTreeNode = groupTreeNode2; } return(groupTreeNode); } List <CollectionViewGroupInternal> parentGroups = lsi.ParentGroups; List <CollectionViewGroupRoot.GroupTreeNode> list = new List <CollectionViewGroupRoot.GroupTreeNode>(parentGroups.Count + 1); CollectionViewGroupRoot.GroupTreeNode result = null; foreach (CollectionViewGroupInternal group in parentGroups) { CollectionViewGroupRoot.GroupTreeNode groupTreeNode = new CollectionViewGroupRoot.GroupTreeNode { Group = group, ContainsItemDirectly = true }; list.Add(groupTreeNode); } for (int i = 0; i < list.Count; i++) { CollectionViewGroupRoot.GroupTreeNode groupTreeNode = list[i]; collectionViewGroupInternal = groupTreeNode.Group.Parent; CollectionViewGroupRoot.GroupTreeNode groupTreeNode3 = null; if (collectionViewGroupInternal == null) { result = groupTreeNode; } else { for (int j = list.Count - 1; j >= 0; j--) { if (list[j].Group == collectionViewGroupInternal) { groupTreeNode3 = list[j]; break; } } if (groupTreeNode3 == null) { groupTreeNode3 = new CollectionViewGroupRoot.GroupTreeNode { Group = collectionViewGroupInternal, FirstChild = groupTreeNode }; list.Add(groupTreeNode3); } else { groupTreeNode.Sibling = groupTreeNode3.FirstChild; groupTreeNode3.FirstChild = groupTreeNode; } } } return(result); }
// Token: 0x060073CC RID: 29644 RVA: 0x0021205C File Offset: 0x0021025C internal void RestoreGrouping(LiveShapingItem lsi, List <AbandonedGroupItem> deleteList) { CollectionViewGroupRoot.GroupTreeNode groupTreeNode = this.BuildGroupTree(lsi); groupTreeNode.ContainsItem = true; this.RestoreGrouping(lsi, groupTreeNode, 0, deleteList); }
// Token: 0x060073C5 RID: 29637 RVA: 0x00211ED0 File Offset: 0x002100D0 internal void AddToSubgroups(object item, LiveShapingItem lsi, bool loading) { this.AddToSubgroups(item, lsi, this, 0, loading); }