private IEnumerable <int> IndexOfOverlap(SelectionCellRange target) { if ((m_sortedRanges.Count <= 0) || SelectedCellsStorage.IsEmpty(target)) { yield break; } var comparer = new ItemRangeComparer(target.ItemRange); var index = this.FindIndex(comparer); if (index < 0) { yield break; } while (index > 0) { if (comparer.Compare(m_sortedRanges[index - 1]) != 0) { break; } index--; } for (int i = index; i < m_sortedRanges.Count; i++) { var wrapper = m_sortedRanges[i]; if (comparer.Compare(wrapper) != 0) { break; } var currentRangeWithItems = wrapper.Value; var overlap = target.Intersect(currentRangeWithItems.CellRange); if (!SelectedCellsStorage.IsEmpty(overlap)) { yield return(wrapper.Index); } } }
private IEnumerable <int> IndexOfOverlap(SelectionCellRange range) { // It improves performance to leave early. if (m_map.Count <= 0) { yield break; } foreach (var entry in m_map.GetEntriesWithin(SelectedCellsStorage.GetArea(range))) { var candidate = entry.Item; var target = candidate.Value; var overlap = range.Intersect(target.CellRange); Debug.Assert(!SelectedCellsStorage.IsEmpty(overlap)); if (!SelectedCellsStorage.IsEmpty(overlap)) { yield return(candidate.Index); } } }
public void UpdateSelectionAfterSourceDataItemReplaced(NotifyCollectionChangedEventArgs e) { Debug.Assert(e.OldItems.Count == e.NewItems.Count); Debug.Assert(e.OldStartingIndex == e.NewStartingIndex); SelectedItemsStorage selectedItemsStorage = m_owner.SelectedItemsStore; SelectedCellsStorage selectedCellsStorage = m_owner.SelectedCellsStore; int oldItemIndex = e.OldStartingIndex; IList oldItems = e.OldItems; IList newItems = e.NewItems; int replacedItemCount = oldItems.Count; int cellRangeCount = selectedCellsStorage.Count; if (oldItemIndex >= 0) { int itemIndex = oldItemIndex; for (int i = 0; i < replacedItemCount; i++) { object newItem = newItems[i]; if (selectedItemsStorage.Contains(itemIndex)) { this.UnselectItems(new SelectionRangeWithItems(itemIndex, oldItems[i])); this.SelectItems(new SelectionRangeWithItems(itemIndex, newItem)); } SelectionCellRange replacedCellRange = new SelectionCellRange( new SelectionRange(itemIndex), new SelectionRange(0, int.MaxValue - 1)); for (int j = 0; j < cellRangeCount; j++) { SelectionCellRangeWithItems cellRangeWithItems = selectedCellsStorage[j]; SelectionCellRange cellRange = cellRangeWithItems.CellRange; if (!cellRange.Intersect(replacedCellRange).IsEmpty) { object[] items = cellRangeWithItems.ItemRangeWithItems.Items; if (items != null) { items[cellRange.ItemRange.GetOffsetFromItemIndex(itemIndex)] = newItem; } } } itemIndex++; } } else { CollectionView sourceItems = m_owner.Items; for (int i = 0; i < replacedItemCount; i++) { object newItem = newItems[i]; int itemIndex = sourceItems.IndexOf(newItem); if (itemIndex < 0) { continue; } if (selectedItemsStorage.Contains(itemIndex)) { this.UnselectItems(new SelectionRangeWithItems(itemIndex, oldItems[i])); this.SelectItems(new SelectionRangeWithItems(itemIndex, newItem)); } SelectionCellRange replacedCellRange = new SelectionCellRange( new SelectionRange(itemIndex), new SelectionRange(0, int.MaxValue - 1)); for (int j = 0; j < cellRangeCount; j++) { SelectionCellRangeWithItems cellRangeWithItems = selectedCellsStorage[j]; SelectionCellRange cellRange = cellRangeWithItems.CellRange; if (!cellRange.Intersect(replacedCellRange).IsEmpty) { object[] items = cellRangeWithItems.ItemRangeWithItems.Items; if (items != null) { items[cellRange.ItemRange.GetOffsetFromItemIndex(itemIndex)] = newItem; } } } } } }
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); }