public void OffsetIndex(int startIndex, int offset) { if (m_sortedRanges.Count == 0) { return; } // Used to offset index after an add or remove from the data source of the grid. var offsetRange = new SelectionRange(startIndex, startIndex + Math.Abs(offset) - 1); var comparer = new ItemRangeComparer(offsetRange); // Find the first range that is greater or that overlaps the target range. var index = this.FindIndex(comparer); if (index < 0) { index = ~index; } else { while (index > 0) { if (comparer.Compare(m_sortedRanges[index - 1]) != 0) { break; } index--; } } var matches = m_sortedRanges.Skip(index).OrderByDescending(item => item.Index).ToList(); // Adjust the range of all ranges greater or that overlaps the target range. foreach (var currentRangeWithItemsWrapper in matches) { Debug.Assert(comparer.Compare(currentRangeWithItemsWrapper) <= 0); var currentRangeIndex = currentRangeWithItemsWrapper.Index; var currentRangeWithItems = currentRangeWithItemsWrapper.Value; var currentRange = currentRangeWithItems.ItemRange; var currentRangeItems = currentRangeWithItems.ItemRangeWithItems.Items; Debug.Assert(!(offsetRange > currentRange)); var currentRangeIntersection = currentRange.Intersect(offsetRange); // The range overlaps. if (!currentRangeIntersection.IsEmpty) { // Should only happen when adding since when we remove data from the source, we remove the // the range from the list. Debug.Assert(offset > 0); SelectionRange topRange; SelectionRange bottomRange; if (currentRange.StartIndex > currentRange.EndIndex) { if (currentRangeIntersection.EndIndex == currentRange.EndIndex) { this[currentRangeIndex] = new SelectionCellRangeWithItems( new SelectionRange(currentRange.StartIndex + offset, currentRange.EndIndex + offset), currentRangeItems, currentRangeWithItems.ColumnRange); continue; } else { topRange = new SelectionRange(currentRange.StartIndex + offset, startIndex + offset); bottomRange = new SelectionRange(startIndex - 1, currentRange.EndIndex); } } else { if (currentRangeIntersection.StartIndex == currentRange.StartIndex) { this[currentRangeIndex] = new SelectionCellRangeWithItems( new SelectionRange(currentRange.StartIndex + offset, currentRange.EndIndex + offset), currentRangeItems, currentRangeWithItems.ColumnRange); continue; } else { topRange = new SelectionRange(currentRange.StartIndex, startIndex - 1); bottomRange = new SelectionRange(startIndex + offset, currentRange.EndIndex + offset); } } object[] topItems = null; object[] bottomItems = null; if (currentRangeItems != null) { topItems = new object[topRange.Length]; Array.Copy(currentRangeItems, 0, topItems, 0, topItems.Length); bottomItems = new object[bottomRange.Length]; Array.Copy(currentRangeItems, topItems.Length, bottomItems, 0, bottomItems.Length); } this[currentRangeIndex] = new SelectionCellRangeWithItems(topRange, topItems, currentRangeWithItems.ColumnRange); this.Insert(currentRangeIndex + 1, new SelectionCellRangeWithItems(bottomRange, bottomItems, currentRangeWithItems.ColumnRange), true); } // The range is greater. else { this[currentRangeIndex] = new SelectionCellRangeWithItems( new SelectionRange(currentRange.StartIndex + offset, currentRange.EndIndex + offset), currentRangeItems, currentRangeWithItems.ColumnRange); } } }
public void Visit(DataGridContext sourceContext, ref bool stopVisit) { object[] items; CollectionView itemsCollection = sourceContext.Items; int count = itemsCollection.Count; if (count == 0) { return; } if (sourceContext.ItemsSourceCollection is DataGridVirtualizingCollectionViewBase) { items = null; } else { items = new object[count]; for (int i = 0; i < count; i++) { items[i] = itemsCollection.GetItemAt(i); } } SelectionRange itemRange = new SelectionRange(0, count - 1); if (sourceContext.DataGridControl.SelectionUnit == SelectionUnit.Row) { sourceContext.DataGridControl.SelectionChangerManager.SelectItems( sourceContext, new SelectionRangeWithItems(itemRange, items)); } else { HashedLinkedList <ColumnBase> columnsByVisiblePosition = sourceContext.ColumnsByVisiblePosition; SelectedItemsStorage selectedColumnStore = new SelectedItemsStorage(null, 8); SelectionRange fullColumnRange = new SelectionRange(0, columnsByVisiblePosition.Count - 1); selectedColumnStore.Add(new SelectionRangeWithItems(fullColumnRange, null)); int index = 0; foreach (ColumnBase column in columnsByVisiblePosition) { if (!column.Visible) { selectedColumnStore.Remove(new SelectionRangeWithItems(new SelectionRange(index), null)); } index++; } int columnRangeCount = selectedColumnStore.Count; for (int i = 0; i < columnRangeCount; i++) { sourceContext.DataGridControl.SelectionChangerManager.SelectCells( sourceContext, new SelectionCellRangeWithItems(itemRange, items, selectedColumnStore[i].Range)); } } }
public SelectionCellRange(SelectionRange itemRange, SelectionRange columnRange) { m_itemRange = itemRange; m_columnRange = columnRange; }
public void OffsetIndexBasedOnSourceNewIndex(int maxOffset) { if (m_dataGridContext == null) { throw new InvalidOperationException("We must have a DataGridContext to find the new index."); } CollectionView sourceItems = m_dataGridContext.Items; for (int i = this.Count - 1; i >= 0; i--) { SelectionRangeWithItems rangeWithItems = m_list[i]; object[] items = rangeWithItems.Items; if (items == null) { throw new InvalidOperationException("We should have items to find the new index."); } object item = items[0]; SelectionRange range = rangeWithItems.Range; int startIndex = Math.Min(range.StartIndex, range.EndIndex); if (maxOffset < 0) { for (int j = 0; j >= maxOffset; j--) { if (object.Equals(sourceItems.GetItemAt(startIndex), item)) { if (j != 0) { SelectionRange newRange = new SelectionRange(range.StartIndex + j, range.EndIndex + j); m_list[i] = new SelectionRangeWithItems(newRange, items); } break; } startIndex--; if (startIndex < 0) { break; } } } else { int sourceItemCount = sourceItems.Count; for (int j = 0; j <= maxOffset; j++) { if (object.Equals(sourceItems.GetItemAt(startIndex), item)) { if (j != 0) { SelectionRange newRange = new SelectionRange(range.StartIndex + j, range.EndIndex + j); m_list[i] = new SelectionRangeWithItems(newRange, items); } break; } startIndex++; if (startIndex >= sourceItemCount) { break; } } } } }
public void OffsetIndex(int startIndex, int offset) { // Used to offset index after an add or remove from the data source of the grid. SelectionRange offsetRange = new SelectionRange( startIndex, startIndex + Math.Abs(offset) - 1); for (int i = this.Count - 1; i >= 0; i--) { SelectionRangeWithItems rangeWithItems = m_list[i]; SelectionRange range = rangeWithItems.Range; if (offsetRange > range) { continue; } SelectionRange rangeIntersection = range.Intersect(offsetRange); object[] originalItems = rangeWithItems.Items; if (!rangeIntersection.IsEmpty) { // Should only happen when adding since when we remove data from the source, we remove the // the range from the list. Debug.Assert(offset > 0); // Offset the index higher than the start index of the new added item SelectionRange topRange; SelectionRange bottomRange; if (range.StartIndex > range.EndIndex) { if (rangeIntersection.EndIndex == range.EndIndex) { SelectionRange newRange = new SelectionRange(range.StartIndex + offset, range.EndIndex + offset); m_list[i] = new SelectionRangeWithItems(newRange, originalItems); continue; } else { int bottomRangeEndIndex = startIndex + offset; bottomRange = new SelectionRange(startIndex - 1, range.EndIndex); topRange = new SelectionRange(range.Length - bottomRange.Length - 1 + bottomRangeEndIndex, bottomRangeEndIndex); } } else { if (rangeIntersection.StartIndex == range.StartIndex) { SelectionRange newRange = new SelectionRange(range.StartIndex + offset, range.EndIndex + offset); m_list[i] = new SelectionRangeWithItems(newRange, originalItems); continue; } else { int bottomRangeStartIndex = startIndex + offset; topRange = new SelectionRange(range.StartIndex, startIndex - 1); bottomRange = new SelectionRange(bottomRangeStartIndex, range.Length - topRange.Length - 1 + bottomRangeStartIndex); } } object[] topItems = null; object[] bottomItems = null; if (originalItems != null) { topItems = new object[topRange.Length]; Array.Copy(originalItems, 0, topItems, 0, topItems.Length); bottomItems = new object[bottomRange.Length]; Array.Copy(originalItems, topItems.Length, bottomItems, 0, bottomItems.Length); } m_list[i] = new SelectionRangeWithItems(topRange, topItems); m_list.Insert(i + 1, new SelectionRangeWithItems(bottomRange, bottomItems)); } else { // Offset the index by the count added SelectionRange newRange = new SelectionRange(range.StartIndex + offset, range.EndIndex + offset); m_list[i] = new SelectionRangeWithItems(newRange, originalItems); } } }
public bool Remove(SelectionRangeWithItems rangeWithItemsToRemove) { bool removed = false; SelectionRange rangeToRemove = rangeWithItemsToRemove.Range; object[] itemsToRemove = rangeWithItemsToRemove.Items; int itemsToRemoveCount = (itemsToRemove == null) ? 0 : itemsToRemove.Length; int itemOffsetToRemove = 0; bool rangeToRemoveIsEmpty = rangeToRemove.IsEmpty; do { for (int i = m_list.Count - 1; i >= 0; i--) { SelectionRangeWithItems rangeWithItems = m_list[i]; SelectionRange range = rangeWithItems.Range; SelectionRange rangeIntersection; object[] oldRangeItems = rangeWithItems.Items; if (rangeToRemoveIsEmpty) { int itemOffset = Array.IndexOf(oldRangeItems, itemsToRemove[itemOffsetToRemove]); if (itemOffset == -1) { continue; } rangeIntersection = new SelectionRange(range.GetIndexFromItemOffset(itemOffset)); } else { rangeIntersection = range.Intersect(rangeToRemove); if (rangeIntersection.IsEmpty) { continue; } if (!rangeWithItems.IsItemsEqual(rangeIntersection, rangeWithItemsToRemove)) { continue; } } removed = true; m_itemsCount -= rangeIntersection.Length; SelectionRange[] newRanges = range.Exclude(rangeIntersection); if (newRanges.Length == 0) { m_list.RemoveAt(i); } else { SelectionRange newRange = newRanges[0]; m_list[i] = new SelectionRangeWithItems(newRange, rangeWithItems.GetItems(newRange)); if (newRanges.Length > 1) { Debug.Assert(newRanges.Length == 2); newRange = newRanges[1]; m_list.Insert(i + 1, new SelectionRangeWithItems(newRange, rangeWithItems.GetItems(newRange))); } } } itemOffsetToRemove++; } while((rangeToRemoveIsEmpty) && (itemOffsetToRemove < itemsToRemoveCount)); return(removed); }
public bool Remove(SelectionCellRangeWithItems cellRangeWithItemsToRemove) { if (cellRangeWithItemsToRemove.CellRange.IsEmpty) { return(true); } bool removed = false; SelectionCellRange cellRangeToRemove = cellRangeWithItemsToRemove.CellRange; object[] itemsToRemove = cellRangeWithItemsToRemove.ItemRangeWithItems.Items; int itemsToRemoveCount = (itemsToRemove == null) ? 0 : itemsToRemove.Length; int itemOffsetToRemove = 0; bool itemRangeToRemoveIsEmpty = cellRangeToRemove.ItemRange.IsEmpty; do { for (int i = m_list.Count - 1; i >= 0; i--) { SelectionCellRangeWithItems cellRangeWithItems = m_list[i]; SelectionRange itemRange = cellRangeWithItems.ItemRange; SelectionCellRange cellRange = cellRangeWithItems.CellRange; SelectionRangeWithItems itemRangeWithItems = cellRangeWithItems.ItemRangeWithItems; SelectionCellRange cellRangeIntersection; object[] oldRangeItems = itemRangeWithItems.Items; if (itemRangeToRemoveIsEmpty) { int itemOffset = Array.IndexOf(oldRangeItems, itemsToRemove[itemOffsetToRemove]); if (itemOffset == -1) { continue; } int itemIndex = itemRange.GetIndexFromItemOffset(itemOffset); cellRangeIntersection = new SelectionCellRange( new SelectionRange(itemIndex, itemIndex), cellRangeWithItems.ColumnRange.Intersect(cellRangeToRemove.ColumnRange)); } else { cellRangeIntersection = cellRange.Intersect(cellRangeToRemove); if (cellRangeIntersection.IsEmpty) { continue; } if (!itemRangeWithItems.IsItemsEqual( cellRangeIntersection.ItemRange, cellRangeWithItemsToRemove.ItemRangeWithItems)) { continue; } } removed = true; m_cellsCount -= cellRangeIntersection.Length; SelectionCellRange[] newCellRanges = cellRange.Exclude(cellRangeIntersection); if (newCellRanges.Length == 0) { m_list.RemoveAt(i); } else { SelectionCellRange newCellRange = newCellRanges[0]; m_list[i] = new SelectionCellRangeWithItems( newCellRange.ItemRange, itemRangeWithItems.GetItems(newCellRange.ItemRange), newCellRange.ColumnRange); for (int j = 1; j < newCellRanges.Length; j++) { newCellRange = newCellRanges[j]; m_list.Insert(i + j, new SelectionCellRangeWithItems( newCellRange.ItemRange, itemRangeWithItems.GetItems(newCellRange.ItemRange), newCellRange.ColumnRange)); } } } itemOffsetToRemove++; } while((itemRangeToRemoveIsEmpty) && (itemOffsetToRemove < itemsToRemoveCount)); return(removed); }
public void OffsetIndex(int startIndex, int offset) { if (m_map.Count == 0) { return; } // Used to offset index after an add or remove from the data source of the grid. var offsetRange = new SelectionRange(startIndex, startIndex + Math.Abs(offset) - 1); var entries = m_map.GetEntriesWithin(new RSTree2D <SelectionCellRangeWithItemsWrapper> .Area(startIndex, int.MaxValue - startIndex, 0, int.MaxValue)).OrderByDescending(e => e.Item.Index).ToList(); // Adjust the range of all ranges greater or that overlaps the target range. foreach (var entry in entries) { var currentRangeWithItemsWrapper = entry.Item; var currentRangeIndex = currentRangeWithItemsWrapper.Index; var currentRangeWithItems = currentRangeWithItemsWrapper.Value; var currentRange = currentRangeWithItems.ItemRange; var currentRangeItems = currentRangeWithItems.ItemRangeWithItems.Items; Debug.Assert(!(offsetRange > currentRange)); var currentRangeIntersection = currentRange.Intersect(offsetRange); // The range overlaps. if (!currentRangeIntersection.IsEmpty) { // Should only happen when adding since when we remove data from the source, we remove the // the range from the list. Debug.Assert(offset > 0); SelectionRange topRange; SelectionRange bottomRange; if (currentRange.StartIndex > currentRange.EndIndex) { if (currentRangeIntersection.EndIndex == currentRange.EndIndex) { this[currentRangeIndex] = new SelectionCellRangeWithItems( new SelectionRange(currentRange.StartIndex + offset, currentRange.EndIndex + offset), currentRangeItems, currentRangeWithItems.ColumnRange); continue; } else { topRange = new SelectionRange(currentRange.StartIndex + offset, startIndex + offset); bottomRange = new SelectionRange(startIndex - 1, currentRange.EndIndex); } } else { if (currentRangeIntersection.StartIndex == currentRange.StartIndex) { this[currentRangeIndex] = new SelectionCellRangeWithItems( new SelectionRange(currentRange.StartIndex + offset, currentRange.EndIndex + offset), currentRangeItems, currentRangeWithItems.ColumnRange); continue; } else { topRange = new SelectionRange(currentRange.StartIndex, startIndex - 1); bottomRange = new SelectionRange(startIndex + offset, currentRange.EndIndex + offset); } } object[] topItems = null; object[] bottomItems = null; if (currentRangeItems != null) { topItems = new object[topRange.Length]; Array.Copy(currentRangeItems, 0, topItems, 0, topItems.Length); bottomItems = new object[bottomRange.Length]; Array.Copy(currentRangeItems, topItems.Length, bottomItems, 0, bottomItems.Length); } this[currentRangeIndex] = new SelectionCellRangeWithItems(topRange, topItems, currentRangeWithItems.ColumnRange); this.Insert(currentRangeIndex + 1, new SelectionCellRangeWithItems(bottomRange, bottomItems, currentRangeWithItems.ColumnRange), true); } // The range is greater. else { this[currentRangeIndex] = new SelectionCellRangeWithItems( new SelectionRange(currentRange.StartIndex + offset, currentRange.EndIndex + offset), currentRangeItems, currentRangeWithItems.ColumnRange); } } }