Example #1
0
        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);
                }
            }
        }
Example #2
0
        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);
        }
Example #8
0
        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);
                }
            }
        }