internal int BinarySearchRawItem(RawItem value, IComparer <RawItem> comparer) { if (comparer == null) { throw new ArgumentNullException("comparer"); } if (m_sortedRawItems == null) { return(-1); // ~0 } Debug.Assert((m_sortedRawItems.Count == this.ItemCount) || (this is DataGridCollectionViewGroupRoot)); int low = 0; int hi = (m_sortedRawItems.Count) - 1; while (low <= hi) { int compareResult; int median = (low + ((hi - low) >> 1)); RawItem medianRawItem = m_sortedRawItems[median]; // We exclude ourself from the research because we seek for a new valid position if (medianRawItem == value) { if (low == hi) { return(low); } median++; medianRawItem = m_sortedRawItems[median]; } try { compareResult = comparer.Compare(medianRawItem, 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); }
internal void Add(object dataItem, RawItem rawItem) { Debug.Assert(dataItem != null); Debug.Assert(rawItem != null); Debug.Assert(dataItem == rawItem.DataItem); RawItem single; RawItem[] multiple; if (m_singleMap.TryGetValue(dataItem, out single)) { Debug.Assert(rawItem != single, "It's not normal to be called twice for the same RawItem."); m_multiMap.Add(dataItem, new RawItem[] { single, rawItem }); m_singleMap.Remove(dataItem); } else if (m_multiMap.TryGetValue(dataItem, out multiple)) { Debug.Assert(!multiple.Contains(rawItem), "It's not normal to be called twice for the same RawItem."); var length = multiple.Length; Array.Resize <RawItem>(ref multiple, length + 1); multiple[length] = rawItem; m_multiMap[dataItem] = multiple; } else { m_singleMap.Add(dataItem, rawItem); } }
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); }
internal virtual void MoveRawItem(int oldIndex, int newIndex) { Debug.Assert(this.IsBottomLevel); Debug.Assert(m_sortedRawItems != null); if (m_sortedRawItems == null) { return; } RawItem rawItem = m_sortedRawItems[oldIndex]; m_sortedRawItems.RemoveAt(oldIndex); m_sortedRawItems.Insert(newIndex, rawItem); int startIndex = Math.Min(oldIndex, newIndex); int endIndex = Math.Max(oldIndex, newIndex); for (int i = startIndex; i <= endIndex; i++) { m_sortedRawItems[i].SetSortedIndex(i); } this.ProtectedItems.Move(oldIndex, newIndex); }
internal virtual void InsertRawItem(int index, RawItem rawItem) { Debug.Assert(this.IsBottomLevel); if (m_sortedRawItems == null) { m_sortedRawItems = new List <RawItem>(4); } 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); }
internal override 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--; 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); } }
internal void SortRootRawItems(SortDescriptionInfo[] sortDescriptionInfos, List <RawItem> globalRawItems) { Debug.Assert(this.IsBottomLevel); int itemCount = m_sortedRawItems.Count; if (itemCount == 0) { return; } 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++) { RawItem newRawItem = globalRawItems[indexes[i]]; newRawItem.SetSortedIndex(index); m_sortedRawItems[index] = newRawItem; index++; } }
internal void Remove(object dataItem, RawItem rawItem) { Debug.Assert(dataItem != null); Debug.Assert(rawItem != null); Debug.Assert(dataItem == rawItem.DataItem); if (m_singleMap.Remove(dataItem)) { return; } RawItem[] multiple; if (!m_multiMap.TryGetValue(dataItem, out multiple)) { return; } var length = multiple.Length; if (length == 2) { if (multiple[0] == rawItem) { m_singleMap.Add(dataItem, multiple[1]); m_multiMap.Remove(dataItem); } else if (multiple[1] == rawItem) { m_singleMap.Add(dataItem, multiple[0]); m_multiMap.Remove(dataItem); } } else { Debug.Assert(length > 2); var index = Array.IndexOf(multiple, rawItem); if (index < 0) { return; } RawItem[] copy = new RawItem[length - 1]; if (index > 0) { Array.Copy(multiple, 0, copy, 0, index); } if (index < length - 1) { Array.Copy(multiple, index + 1, copy, index, length - index - 1); } m_multiMap[dataItem] = copy; } }
internal int RawItemIndexOf(RawItem rawItem) { Debug.Assert(m_sortedRawItems != null); if (m_sortedRawItems == null) { return(-1); } return(m_sortedRawItems.IndexOf(rawItem)); }
internal void RemoveRawItem(RawItem rawItem) { if (!this.IsBottomLevel) { throw new InvalidOperationException("An attempt was made to remove a data item from a group other than the bottom-level group."); } int index = this.RawItemIndexOf(rawItem); this.RemoveRawItemAt(index); }
internal bool Contains(object dataItem) { DataGridCollectionView collectionView = this.GetCollectionView(); if (collectionView != null) { RawItem rawItem = collectionView.GetFirstRawItemFromDataItem(dataItem); if (rawItem != null) { return(rawItem.ParentGroup == this); } } return(false); }
internal DataGridCollectionViewGroup GetGroup( RawItem rawItem, int level, CultureInfo culture, ObservableCollection <GroupDescription> groupByList, 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); DataGridGroupDescription dataGridGroupDescription = m_subGroupBy as DataGridGroupDescription; DataGridCollectionViewGroup group; if (dataGridGroupDescription != null) { group = m_groupsDictionary[DataGridCollectionViewGroup.GetHashKeyFromName(groupName)] as DataGridCollectionViewGroup; } else { int itemCount = this.ItemCount; group = null; for (int i = 0; i < itemCount; i++) { DataGridCollectionViewGroup tempGroup = this.ProtectedItems[i] as DataGridCollectionViewGroup; if (m_subGroupBy.NamesMatch(tempGroup.Name, groupName)) { group = tempGroup; break; } } } if (group == null) { group = this.CreateSubGroup( groupName, level, groupByList, groupSortComparers); } return(group); }
internal override void InsertRawItem(int index, RawItem rawItem) { Debug.Assert(this.IsBottomLevel); m_globalRawItemCount++; 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); }
internal override void InsertRawItem( int index, RawItem rawItem ) { Debug.Assert( this.IsBottomLevel ); m_globalRawItemCount++; 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 ); }
internal int IndexOf(object dataItem) { DataGridCollectionView collectionView = this.GetCollectionView(); if (collectionView != null) { RawItem rawItem = collectionView.GetFirstRawItemFromDataItem(dataItem); if ((rawItem != null) && (rawItem.ParentGroup == this)) { return(rawItem.SortedIndex); } } return(-1); }
internal override void MoveRawItem(int oldIndex, int newIndex) { Debug.Assert(this.IsBottomLevel); RawItem rawItem = m_sortedRawItems[oldIndex]; m_sortedRawItems.RemoveAt(oldIndex); m_sortedRawItems.Insert(newIndex, rawItem); int startIndex = Math.Min(oldIndex, newIndex); int endIndex = Math.Max(oldIndex, newIndex); for (int i = startIndex; i <= endIndex; i++) { m_sortedRawItems[i].SetSortedIndex(i); } }
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); }
internal virtual void RemoveRawItemAt(int index) { Debug.Assert(this.IsBottomLevel); Debug.Assert(m_sortedRawItems != null); if (m_sortedRawItems == null) { return; } if (index != -1) { m_globalRawItemCount--; DataGridCollectionViewGroup parent = m_parent; while (parent != null) { parent.m_globalRawItemCount--; parent = parent.Parent; } int count = m_sortedRawItems.Count; 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 int IndexOf(object item) { if (item is DataGridCollectionViewGroup) { return(this.ProtectedItems.IndexOf(item)); } DataGridCollectionView collectionView = this.GetCollectionView(); if (collectionView != null) { RawItem rawItem = collectionView.GetFirstRawItemFromDataItem(item); if ((rawItem != null) && (rawItem.ParentGroup == this)) { return(rawItem.SortedIndex); } } return(-1); }
internal DataGridCollectionViewGroup GetGroup( RawItem rawItem, int level, CultureInfo culture, ObservableCollection<GroupDescription> groupByList, 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 ); DataGridGroupDescription dataGridGroupDescription = m_subGroupBy as DataGridGroupDescription; DataGridCollectionViewGroup group; if( dataGridGroupDescription != null ) { group = m_groupsDictionary[ DataGridCollectionViewGroup.GetHashKeyFromName( groupName ) ] as DataGridCollectionViewGroup; } else { int itemCount = this.ItemCount; group = null; for( int i = 0; i < itemCount; i++ ) { DataGridCollectionViewGroup tempGroup = this.ProtectedItems[ i ] as DataGridCollectionViewGroup; if( m_subGroupBy.NamesMatch( tempGroup.Name, groupName ) ) { group = tempGroup; break; } } } if( group == null ) { group = this.CreateSubGroup( groupName, level, groupByList, groupSortComparers ); } return group; }
internal int RawItemIndexOf( RawItem rawItem ) { Debug.Assert( m_sortedRawItems != null ); if( m_sortedRawItems == null ) return -1; return m_sortedRawItems.IndexOf( rawItem ); }
internal int BinarySearchRawItem( RawItem value, IComparer<RawItem> comparer ) { if( comparer == null ) throw new ArgumentNullException( "comparer" ); if( m_sortedRawItems == null ) return -1; // ~0 Debug.Assert( ( m_sortedRawItems.Count == this.ItemCount ) || ( this is DataGridCollectionViewGroupRoot ) ); int low = 0; int hi = ( m_sortedRawItems.Count ) - 1; while( low <= hi ) { int compareResult; int median = ( low + ( ( hi - low ) >> 1 ) ); RawItem medianRawItem = m_sortedRawItems[ median ]; // We exclude ourself from the research because we seek for a new valid position if( medianRawItem == value ) { if( low == hi ) return low; median++; medianRawItem = m_sortedRawItems[ median ]; } try { compareResult = comparer.Compare( medianRawItem, 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; }
internal virtual void InsertRawItem( int index, RawItem rawItem ) { Debug.Assert( this.IsBottomLevel ); if( m_sortedRawItems == null ) m_sortedRawItems = new List<RawItem>( 4 ); 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 ); }
internal void RemoveRawItem( RawItem rawItem ) { if( !this.IsBottomLevel ) throw new InvalidOperationException( "An attempt was made to remove a data item from a group other than the bottom-level group." ); int index = this.RawItemIndexOf( rawItem ); this.RemoveRawItemAt( index ); }