public bool IsItemsEqual(SelectionRange rangeIntersection, SelectionRangeWithItems rangeWithItemsToCompare)
        {
            object[] itemsToCompare = rangeWithItemsToCompare.m_items;

            if ((m_items == null) || (itemsToCompare == null))
            {
                return(true);
            }

            SelectionRange rangeToCompare = rangeWithItemsToCompare.Range;
            int            startIndex     = Math.Min(rangeIntersection.StartIndex, rangeIntersection.EndIndex);
            int            itemIndex1     = Math.Abs(startIndex - m_range.StartIndex);
            int            itemIndex2     = Math.Abs(startIndex - rangeToCompare.StartIndex);
            bool           inversedRange1 = m_range.StartIndex > m_range.EndIndex;
            bool           inversedRange2 = rangeToCompare.StartIndex > rangeToCompare.EndIndex;
            int            count          = rangeIntersection.Length;

            for (int i = 0; i < count; i++)
            {
                if (!object.Equals(m_items[itemIndex1], itemsToCompare[itemIndex2]))
                {
                    return(false);
                }

                itemIndex1 = inversedRange1 ? itemIndex1 - 1 : itemIndex1 + 1;
                itemIndex2 = inversedRange2 ? itemIndex2 - 1 : itemIndex2 + 1;
            }

            return(true);
        }
        public int IndexOf(object item)
        {
            int indexOffset = 0;
            int count       = m_list.Count;

            for (int i = 0; i < count; i++)
            {
                SelectionRangeWithItems rangeWithItems = m_list[i];
                object[] items = rangeWithItems.Items;

                if (items != null)
                {
                    int index = Array.IndexOf <object>(items, item);

                    if (index != -1)
                    {
                        return(indexOffset + index);
                    }
                }

                indexOffset += rangeWithItems.Length;
            }

            return(-1);
        }
        public object this[int index]
        {
            get
            {
                if ((index < 0) || (index >= m_list.ItemsCount))
                {
                    throw new ArgumentOutOfRangeException("index", "The index must be equal or greater than zero and less than Count.");
                }

                int oldIndexOffset = 0;
                int indexOffset    = 0;
                int count          = m_list.Count;

                for (int i = 0; i < count; i++)
                {
                    SelectionRangeWithItems rangeWithItems = m_list[i];
                    indexOffset += rangeWithItems.Length;

                    if (index < indexOffset)
                    {
                        return(rangeWithItems.GetItem(m_list.DataGridContext, index - oldIndexOffset));
                    }

                    oldIndexOffset = indexOffset;
                }

                throw new ArgumentOutOfRangeException("index", "The index must be less than Count.");
            }
            set
            {
                throw new NotSupportedException();
            }
        }
    public SelectionCellRangeWithItems( SelectionRange itemRange, object[] items, SelectionRange columnRange )
    {
      if( ( items != null ) && ( items.Length != itemRange.Length ) ) 
        throw new ArgumentException( "itemRange and items must have the same length." );

      m_itemRangeWithItems = new SelectionRangeWithItems( itemRange, items );
      m_columnRange = columnRange;
    }
    public void Visit( DataGridContext sourceContext, int startSourceDataItemIndex, int endSourceDataItemIndex, ref bool stopVisit )
    {
      SelectionManager selectionChangerManager = sourceContext.DataGridControl.SelectionChangerManager;

      if( m_selectedColumns != null )
      {
        int columnCount = sourceContext.Columns.Count;

        if( columnCount == 0 )
          return;

        SelectionRange contextColumnMaxRange = new SelectionRange( 0, columnCount - 1 );

        for( int i = 0; i < m_selectedColumns.Length; i++ )
        {
          SelectionRange selectionRange = m_selectedColumns[ i ];
          SelectionRange intersectionSelectionRange = selectionRange.Intersect( contextColumnMaxRange );

          if( intersectionSelectionRange.IsEmpty )
            continue;

#if DEBUG
          string action = ( m_unselect ) ? "Removing" : "Adding";
          Debug.WriteLine( "Selection : " + action + " cell : (" + startSourceDataItemIndex.ToString() + " - " + endSourceDataItemIndex.ToString() + ") - ("
             + intersectionSelectionRange.StartIndex.ToString() + " - " + intersectionSelectionRange.EndIndex.ToString() + ")" );
#endif

          var cellRange = new SelectionCellRangeWithItems( new SelectionRange( startSourceDataItemIndex, endSourceDataItemIndex ), null, intersectionSelectionRange );

          if( m_unselect )
          {
            selectionChangerManager.UnselectCells( sourceContext, cellRange );
          }
          else
          {
            selectionChangerManager.SelectCells( sourceContext, cellRange );
          }
        }
      }
      else
      {
#if DEBUG
        string action = ( m_unselect ) ? "Removing" : "Adding";
        Debug.WriteLine( "Selection : " + action + " Adding item : " + startSourceDataItemIndex.ToString() + " - " + endSourceDataItemIndex.ToString() );
#endif
        var itemRange = new SelectionRangeWithItems( new SelectionRange( startSourceDataItemIndex, endSourceDataItemIndex ), null );

        if( m_unselect )
        {
          selectionChangerManager.UnselectItems( sourceContext, itemRange );
        }
        else
        {
          selectionChangerManager.SelectItems( sourceContext, itemRange );
        }
      }
    }
        public SelectionCellRangeWithItems(SelectionRange itemRange, object[] items, SelectionRange columnRange)
        {
            if ((items != null) && (items.Length != itemRange.Length))
            {
                throw new ArgumentException("itemRange and items must have the same length.");
            }

            m_itemRangeWithItems = new SelectionRangeWithItems(itemRange, items);
            m_columnRange        = columnRange;
        }
        public void Insert(int index, SelectionRangeWithItems rangeWithItems)
        {
            Debug.Assert(!this.Contains(rangeWithItems.Range));
            m_itemsCount += rangeWithItems.Length;

            SelectedItemsStorage.UpdateSelectionRangeWithItemsFromAdd(
                m_dataGridContext, rangeWithItems, ref rangeWithItems);

            m_list.Insert(index, rangeWithItems);
        }
        public void Visit(DataGridContext sourceContext, int startSourceDataItemIndex, int endSourceDataItemIndex, ref bool stopVisit)
        {
            SelectionManager selectionChangerManager = sourceContext.DataGridControl.SelectionChangerManager;

            if (m_selectedColumns != null)
            {
                int columnCount = sourceContext.Columns.Count;

                if (columnCount == 0)
                {
                    return;
                }

                SelectionRange contextColumnMaxRange = new SelectionRange(0, columnCount - 1);

                for (int i = 0; i < m_selectedColumns.Length; i++)
                {
                    SelectionRange selectionRange             = m_selectedColumns[i];
                    SelectionRange intersectionSelectionRange = selectionRange.Intersect(contextColumnMaxRange);

                    if (intersectionSelectionRange.IsEmpty)
                    {
                        continue;
                    }


                    var cellRange = new SelectionCellRangeWithItems(new SelectionRange(startSourceDataItemIndex, endSourceDataItemIndex), null, intersectionSelectionRange);

                    if (m_unselect)
                    {
                        selectionChangerManager.UnselectCells(sourceContext, cellRange);
                    }
                    else
                    {
                        selectionChangerManager.SelectCells(sourceContext, cellRange);
                    }
                }
            }
            else
            {
                var itemRange = new SelectionRangeWithItems(new SelectionRange(startSourceDataItemIndex, endSourceDataItemIndex), null);

                if (m_unselect)
                {
                    selectionChangerManager.UnselectItems(sourceContext, itemRange);
                }
                else
                {
                    selectionChangerManager.SelectItems(sourceContext, itemRange);
                }
            }
        }
 public SelectionRangeWithItems this[int index]
 {
     get
     {
         return(m_list[index]);
     }
     set
     {
         SelectionRangeWithItems oldRangeWithItems = m_list[index];
         m_list[index] = value;
         m_itemsCount += value.Length - oldRangeWithItems.Length;
     }
 }
Exemple #10
0
        public int Add(SelectionCellRangeWithItems cellRangeWithItems)
        {
            m_cellsCount += cellRangeWithItems.Length;
            SelectionRangeWithItems itemRangeWithItems = cellRangeWithItems.ItemRangeWithItems;

            SelectedItemsStorage.UpdateSelectionRangeWithItemsFromAdd(
                m_dataGridContext, itemRangeWithItems, ref itemRangeWithItems);

            m_list.Add(new SelectionCellRangeWithItems(
                           itemRangeWithItems.Range, itemRangeWithItems.Items, cellRangeWithItems.ColumnRange));

            return(m_list.Count - 1);
        }
Exemple #11
0
        public void Insert(int index, SelectionCellRangeWithItems cellRangeWithItems)
        {
            Debug.Assert(!this.Contains(cellRangeWithItems.CellRange));
            m_cellsCount += cellRangeWithItems.Length;

            SelectionRangeWithItems itemRangeWithItems = cellRangeWithItems.ItemRangeWithItems;

            SelectedItemsStorage.UpdateSelectionRangeWithItemsFromAdd(
                m_dataGridContext, itemRangeWithItems, ref itemRangeWithItems);

            m_list.Insert(
                index, new SelectionCellRangeWithItems(
                    itemRangeWithItems.Range, itemRangeWithItems.Items, cellRangeWithItems.ColumnRange));
        }
        public void UpdateSelectionAfterSourceDataItemRemoved(NotifyCollectionChangedEventArgs e)
        {
            int   oldStartingIndex  = e.OldStartingIndex;
            IList removedItemsList  = e.OldItems;
            int   removedItemsCount = removedItemsList.Count;

            m_sourceChanges.Add(new SourceChangeInfo(e.Action, oldStartingIndex, removedItemsCount, removedItemsList));

            if (oldStartingIndex == -1)
            {
                foreach (object item in removedItemsList)
                {
                    SelectionRangeWithItems rangeWithItemsToRemove = new SelectionRangeWithItems(SelectionRange.Empty, new object[] { item });

                    m_itemsToSelect.Remove(rangeWithItemsToRemove);
                    m_itemsToUnselect.Remove(rangeWithItemsToRemove);

                    SelectionCellRangeWithItems cellRangeWithItemsToRemove = new SelectionCellRangeWithItems(
                        SelectionRange.Empty, new object[] { item }, new SelectionRange(0, int.MaxValue - 1));

                    m_cellsToSelect.Remove(cellRangeWithItemsToRemove);
                    m_cellsToUnselect.Remove(cellRangeWithItemsToRemove);
                }

                // Seek out in a max range of removedItemsCount the new position for actually selected item.
                m_itemsToSelect.OffsetIndexBasedOnSourceNewIndex(-removedItemsCount);
                m_itemsToUnselect.OffsetIndexBasedOnSourceNewIndex(-removedItemsCount);
                m_cellsToSelect.OffsetIndexBasedOnSourceNewIndex(-removedItemsCount);
                m_cellsToUnselect.OffsetIndexBasedOnSourceNewIndex(-removedItemsCount);
            }
            else
            {
                SelectionRange          itemRange = new SelectionRange(oldStartingIndex, oldStartingIndex + removedItemsCount - 1);
                SelectionRangeWithItems rangeWithItemsToRemove = new SelectionRangeWithItems(itemRange, null);
                m_itemsToSelect.Remove(rangeWithItemsToRemove);
                m_itemsToUnselect.Remove(rangeWithItemsToRemove);
                m_itemsToSelect.OffsetIndex(oldStartingIndex, -removedItemsCount);
                m_itemsToUnselect.OffsetIndex(oldStartingIndex, -removedItemsCount);

                SelectionCellRangeWithItems cellRangeWithItemsToRemove = new SelectionCellRangeWithItems(
                    itemRange, null, new SelectionRange(0, int.MaxValue - 1));

                m_cellsToSelect.Remove(cellRangeWithItemsToRemove);
                m_cellsToUnselect.Remove(cellRangeWithItemsToRemove);
                m_cellsToSelect.OffsetIndex(oldStartingIndex, -removedItemsCount);
                m_cellsToUnselect.OffsetIndex(oldStartingIndex, -removedItemsCount);
            }
        }
        private IEnumerable <object> EnumerateItems(SelectionRangeWithItems range, DataGridContext dataGridContext, int itemsCount)
        {
            var startAt = range.Range.StartIndex;
            var endAt   = range.Range.EndIndex;
            var min     = Math.Min(startAt, endAt);
            var max     = Math.Max(startAt, endAt);

            if (startAt > endAt)
            {
                var upperLimit = Math.Min(startAt, itemsCount - 1);

                for (int i = upperLimit; i >= endAt; i--)
                {
                    object item;

                    try
                    {
                        item = range.GetItem(dataGridContext, startAt - i);
                    }
                    catch (ArgumentOutOfRangeException)
                    {
                        continue;
                    }

                    yield return(item);
                }
            }
            else
            {
                var upperLimit = Math.Min(endAt, itemsCount - 1);

                for (int i = startAt; i <= upperLimit; i++)
                {
                    object item;

                    try
                    {
                        item = range.GetItem(dataGridContext, i - startAt);
                    }
                    catch (ArgumentOutOfRangeException)
                    {
                        break;
                    }

                    yield return(item);
                }
            }
        }
        public bool SelectJustThisItem(int itemIndex, object item)
        {
            bool selectionDone = true;

            m_toDeferSelect.Clear();

            SelectionRangeWithItems rangeWithItemsToSelect = new SelectionRangeWithItems(itemIndex, item);
            SelectionRange          range = rangeWithItemsToSelect.Range;

            if (m_itemsToSelect.Contains(range))
            {
                selectionDone = false;
            }

            m_itemsToSelect.Clear();
            SelectedItemsStorage selectedItemsInChange = m_owner.SelectedItemsStore;

            if (selectedItemsInChange.Contains(range))
            {
                if (!m_itemsToUnselect.Contains(range))
                {
                    selectionDone = false;
                }

                m_itemsToUnselect.Clear();

                foreach (SelectionRangeWithItems selectedRangeWithItems in selectedItemsInChange)
                {
                    m_itemsToUnselect.Add(selectedRangeWithItems);
                }

                m_itemsToUnselect.Remove(rangeWithItemsToSelect);
            }
            else
            {
                m_itemsToSelect.Add(rangeWithItemsToSelect);
                m_itemsToUnselect.Clear();

                foreach (SelectionRangeWithItems selectedRangeWithItems in selectedItemsInChange)
                {
                    m_itemsToUnselect.Add(selectedRangeWithItems);
                }
            }

            this.UnselectAllCells();
            return(selectionDone);
        }
        void ICollection.CopyTo(Array array, int arrayIndex)
        {
            DataGridContext dataGridContext = m_list.DataGridContext;
            int             count           = m_list.Count;

            for (int i = 0; i < count; i++)
            {
                SelectionRangeWithItems rangeWithItems = m_list[i];
                int rangeLength = rangeWithItems.Length;

                for (int j = 0; j < rangeLength; j++)
                {
                    array.SetValue(rangeWithItems.GetItem(dataGridContext, j), arrayIndex);
                    arrayIndex++;
                }
            }
        }
        public void CopyTo(object[] array, int arrayIndex)
        {
            DataGridContext dataGridContext = m_list.DataGridContext;
            int             count           = m_list.Count;

            for (int i = 0; i < count; i++)
            {
                SelectionRangeWithItems rangeWithItems = m_list[i];
                int rangeLength = rangeWithItems.Length;

                for (int j = 0; j < rangeLength; j++)
                {
                    array[arrayIndex] = rangeWithItems.GetItem(dataGridContext, j);
                    arrayIndex++;
                }
            }
        }
        public void RemoveAt(int index)
        {
            if ((index < 0) || (index >= m_list.ItemsCount))
            {
                throw new ArgumentOutOfRangeException("index", index, "index must be greater than or equal to zero and less than Count.");
            }

            int oldIndexOffset = 0;
            int indexOffset    = 0;
            int count          = m_list.Count;
            SelectionRangeWithItems rangeWithItemsFound = SelectionRangeWithItems.Empty;

            for (int i = 0; i < count; i++)
            {
                SelectionRangeWithItems rangeWithItems = m_list[i];
                indexOffset += rangeWithItems.Length;

                if (index < indexOffset)
                {
                    rangeWithItemsFound = rangeWithItems; // .GetItem( dataGridContext, index - oldIndexOffset );
                    break;
                }

                oldIndexOffset = indexOffset;
            }

            if (!rangeWithItemsFound.IsEmpty)
            {
                DataGridContext  dataGridContext  = m_list.DataGridContext;
                SelectionManager selectionManager = dataGridContext.DataGridControl.SelectionChangerManager;
                selectionManager.Begin();

                try
                {
                    selectionManager.UnselectItems(dataGridContext,
                                                   new SelectionRangeWithItems(
                                                       rangeWithItemsFound.Range.GetIndexFromItemOffset(index - oldIndexOffset),
                                                       rangeWithItemsFound.GetItem(dataGridContext, index - oldIndexOffset)));
                }
                finally
                {
                    selectionManager.End(false, true, true);
                }
            }
        }
        public int Add(SelectionRangeWithItems rangeWithItems)
        {
            Debug.Assert(!this.Contains(rangeWithItems.Range));

            m_itemsCount += rangeWithItems.Length;
            int count = m_list.Count;

            if (count > 0)
            {
                int lastIndex = count - 1;
                SelectionRangeWithItems lastRangeWithItems = m_list[lastIndex];
                SelectionRange          lastRange          = lastRangeWithItems.Range;

                if ((lastRange.EndIndex + 1) == rangeWithItems.Range.StartIndex)
                {
                    Debug.Assert(rangeWithItems.Range.EndIndex > lastRange.EndIndex);

                    SelectedItemsStorage.UpdateSelectionRangeWithItemsFromAdd(
                        m_dataGridContext, rangeWithItems, ref lastRangeWithItems);

                    m_list[lastIndex] = lastRangeWithItems;
                    return(lastIndex);
                }
                else if ((lastRange.EndIndex - 1) == rangeWithItems.Range.StartIndex)
                {
                    Debug.Assert(rangeWithItems.Range.EndIndex < lastRange.EndIndex);

                    SelectedItemsStorage.UpdateSelectionRangeWithItemsFromAdd(
                        m_dataGridContext, rangeWithItems, ref lastRangeWithItems);

                    m_list[lastIndex] = lastRangeWithItems;
                    return(lastIndex);
                }
            }

            SelectedItemsStorage.UpdateSelectionRangeWithItemsFromAdd(
                m_dataGridContext, rangeWithItems, ref rangeWithItems);

            m_list.Add(rangeWithItems);
            return(m_list.Count - 1);
        }
        private IEnumerable <SelectionRangeWithItems> GetUnselectedItemsFromRemove(ICollection <SelectionRangeWithItems> removedRangeWithItems)
        {
            var store = m_owner.SelectedItemsStore;

            if ((store.Count <= 0) || (m_sourceChanges.Count <= 0))
            {
                return(Enumerable.Empty <SelectionRangeWithItems>());
            }

            var unselectedItemsFromRemove = new List <SelectionRangeWithItems>();

            for (int i = 0; i < m_sourceChanges.Count; i++)
            {
                var sourceChangeInfo = m_sourceChanges[i];
                if ((sourceChangeInfo.Action != NotifyCollectionChangedAction.Remove) || (sourceChangeInfo.StartIndex == -1))
                {
                    continue;
                }

                var startIndex       = sourceChangeInfo.StartIndex;
                var removedItemCount = sourceChangeInfo.Count;
                var removedItems     = new object[removedItemCount];

                sourceChangeInfo.Items.CopyTo(removedItems, 0);

                var range = new SelectionRange(startIndex, startIndex + removedItemCount - 1);
                var rangeWithItemsToRemove = new SelectionRangeWithItems(range, removedItems);

                if (removedRangeWithItems != null)
                {
                    removedRangeWithItems.Add(rangeWithItemsToRemove);
                }

                if (store.Contains(rangeWithItemsToRemove))
                {
                    unselectedItemsFromRemove.Add(rangeWithItemsToRemove);
                }
            }

            return(unselectedItemsFromRemove);
        }
        public bool Contains(SelectionRangeWithItems rangeWithItemsToCompare)
        {
            int            count          = m_list.Count;
            SelectionRange rangeToCompare = rangeWithItemsToCompare.Range;

            for (int i = 0; i < count; i++)
            {
                SelectionRangeWithItems rangeWithItem     = m_list[i];
                SelectionRange          rangeIntersection = rangeWithItem.Range.Intersect(rangeToCompare);

                if (!rangeIntersection.IsEmpty)
                {
                    if (rangeWithItemsToCompare.IsItemsEqual(rangeIntersection, rangeWithItem))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
    public static void UpdateSelectionRangeWithItemsFromAdd(
      DataGridContext dataGridContext,
      SelectionRangeWithItems newRangeWithItems,
      ref SelectionRangeWithItems lastRangeWithItems )
    {
      // Only work for adding at the end of an existing range.

      object[] newRangeItems = newRangeWithItems.Items;

      if( ( ( dataGridContext == null )
        || ( ( dataGridContext.ItemsSourceCollection == null ) && ( newRangeItems == null ) )
        || ( dataGridContext.ItemsSourceCollection is DataGridVirtualizingCollectionViewBase ) ) )
      {
        lastRangeWithItems = new SelectionRangeWithItems(
          new SelectionRange( lastRangeWithItems.Range.StartIndex, newRangeWithItems.Range.EndIndex ),
          null );

        return;
      }

      object[] rangeToUpdateItems = lastRangeWithItems.Items;
      object[] newItems;
      int newItemsStartPosition;

      if( newRangeWithItems == lastRangeWithItems )
      {
        if( newRangeItems != null )
          return;

        newItemsStartPosition = 0;
        newItems = new object[ lastRangeWithItems.Length ];
      }
      else
      {
        newItemsStartPosition = lastRangeWithItems.Length;
        newItems = new object[ lastRangeWithItems.Length + newRangeWithItems.Length ];
        Array.Copy( rangeToUpdateItems, newItems, newItemsStartPosition );
      }

      CollectionView items = ( dataGridContext == null ) ? null : dataGridContext.Items;
      int rangeToUpdateStartIndex = lastRangeWithItems.Range.StartIndex;
      int rangeToUpdateEndIndex = lastRangeWithItems.Range.EndIndex;
      int newRangeStartIndex = newRangeWithItems.Range.StartIndex;
      int newRangeEndIndex = newRangeWithItems.Range.EndIndex;

      // If new range have no items set, found the items and set it.
      if( newRangeItems == null )
      {
        if( newRangeEndIndex > newRangeStartIndex )
        {
          for( int i = newRangeStartIndex; i <= newRangeEndIndex; i++ )
          {
            newItems[ newItemsStartPosition ] = items.GetItemAt( i );
            newItemsStartPosition++;
          }
        }
        else
        {
          for( int i = newRangeStartIndex; i >= newRangeEndIndex; i-- )
          {
            newItems[ newItemsStartPosition ] = items.GetItemAt( i );
            newItemsStartPosition++;
          }
        }
      }
      else
      {
        for( int i = 0; i < newRangeItems.Length; i++ )
        {
          newItems[ newItemsStartPosition ] = newRangeItems[ i ];
          newItemsStartPosition++;
        }
      }

      lastRangeWithItems = new SelectionRangeWithItems(
        new SelectionRange( rangeToUpdateStartIndex, newRangeEndIndex ),
        newItems );
    }
    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;
          }
        }
      }
    }
    private List<SelectionRangeWithItems> GetUnselectedItemsFromRemove( out List<SelectionRangeWithItems> removedRangeWithItems )
    {
      List<SelectionRangeWithItems> unselectedItemsFromRemove = new List<SelectionRangeWithItems>( 8 );
      removedRangeWithItems = new List<SelectionRangeWithItems>( 8 );

      int count = m_sourceChanges.Count;

      for( int i = 0; i < count; i++ )
      {
        SourceChangeInfo sourceChangeInfo = m_sourceChanges[ i ];

        if( ( sourceChangeInfo.Action != NotifyCollectionChangedAction.Remove ) || ( sourceChangeInfo.StartIndex == -1 ) )
          continue;

        int startIndex = sourceChangeInfo.StartIndex;
        int removedItemCount = sourceChangeInfo.Count;
        object[] removedItems = new object[ removedItemCount ];
        sourceChangeInfo.Items.CopyTo( removedItems, 0 );

        SelectionRangeWithItems rangeWithItemsToRemove = new SelectionRangeWithItems(
          new SelectionRange( startIndex, startIndex + removedItemCount - 1 ),
          removedItems );

        removedRangeWithItems.Add( rangeWithItemsToRemove );

        if( m_owner.SelectedItemsStore.Contains( rangeWithItemsToRemove ) )
        {
          unselectedItemsFromRemove.Add( rangeWithItemsToRemove );
        }
      }

      return unselectedItemsFromRemove;
    }
    public bool UnselectItems( SelectionRangeWithItems rangeWithItems )
    {
      if( !( m_owner.ItemsSourceCollection is DataGridVirtualizingCollectionViewBase ) )
      {
        if( m_toDeferSelect.Count > 0 )
        {
          foreach( object item in rangeWithItems.Items )
          {
            m_toDeferSelect.Remove( item );
          }
        }
      }

      SelectionRange range = rangeWithItems.Range;

      if( range.IsEmpty )
      {
        // We have no index we have to remove based on item
        bool selectionChanged = false;

        List<SelectionRangeWithItems> itemsRangeToRemove = new List<SelectionRangeWithItems>();
        List<object> itemsToUnselect = new List<object>( rangeWithItems.Items );
        int count = itemsToUnselect.Count;

        for( int i = count - 1; i >= 0; i-- )
        {
          object itemToUnselect = itemsToUnselect[ i ];
          bool selectionAdded = false;

          foreach( SelectionRangeWithItems existingSelectionRangeWithItems in m_itemsToSelect )
          {
            int index = Array.IndexOf( existingSelectionRangeWithItems.Items, itemToUnselect );

            if( index > -1 )
            {
              selectionAdded = true;

              itemsRangeToRemove.Add(
                new SelectionRangeWithItems(
                  existingSelectionRangeWithItems.Range.GetIndexFromItemOffset( index ),
                  itemToUnselect ) );
            }
          }

          if( selectionAdded )
          {
            itemsToUnselect.RemoveAt( i );
          }
        }

        // Remove the currently unselected item from the new range to select
        foreach( SelectionRangeWithItems itemRangeToRemove in itemsRangeToRemove )
        {
          selectionChanged |= m_itemsToSelect.Remove( itemRangeToRemove );
        }

        count = itemsToUnselect.Count;

        for( int i = 0; i < count; i++ )
        {
          object itemToUnselect = itemsToUnselect[ i ];

          foreach( SelectionRangeWithItems existingSelectionRangeWithItems in m_owner.SelectedItemsStore )
          {
            int index = Array.IndexOf( existingSelectionRangeWithItems.Items, itemToUnselect );

            if( index > -1 )
            {
              index = existingSelectionRangeWithItems.Range.GetIndexFromItemOffset( index );

              if( !m_itemsToUnselect.Contains( index ) )
              {
                selectionChanged = true;
                m_itemsToUnselect.Add( new SelectionRangeWithItems( index, itemToUnselect ) );
              }
            }
          }
        }

        return selectionChanged;
      }

      if( range.Length == 1 )
      {
        if( !m_itemsToSelect.Remove( rangeWithItems ) )
        {
          if( !m_owner.SelectedItemsStore.Contains( range ) )
            return false;

          if( m_itemsToUnselect.Contains( range ) )
            return false;

          m_itemsToUnselect.Add( rangeWithItems );
        }

        return true;
      }
      else
      {
        SelectedItemsStorage tempStorage = new SelectedItemsStorage( m_owner, 8 );
        tempStorage.Add( rangeWithItems );

        // Remove the currently selected item from the new range to select
        foreach( SelectionRangeWithItems existingSelectionRangeWithItems in m_itemsToSelect )
        {
          if( !range.Intersect( existingSelectionRangeWithItems.Range ).IsEmpty )
          {
            tempStorage.Remove( existingSelectionRangeWithItems );
          }
        }

        bool selectionChanged = m_itemsToSelect.Remove( rangeWithItems );

        if( tempStorage.Count > 0 )
        {
          selectionChanged = true;

          foreach( SelectionRangeWithItems rangeWithItemsToAdd in tempStorage )
          {
            Debug.Assert( !m_itemsToUnselect.Contains( rangeWithItemsToAdd.Range ) );
            m_itemsToUnselect.Add( rangeWithItemsToAdd );
          }
        }

        return selectionChanged;
      }
    }
Exemple #25
0
        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--)
            {
                SelectionCellRangeWithItems cellRangeWithItems = m_list[i];
                SelectionRangeWithItems     itemRangeWithItems = cellRangeWithItems.ItemRangeWithItems;
                object[] items = itemRangeWithItems.Items;

                if (items == null)
                {
                    throw new InvalidOperationException("We should have items to find the new index.");
                }

                object         item       = items[0];
                SelectionRange itemRange  = itemRangeWithItems.Range;
                int            startIndex = Math.Min(itemRange.StartIndex, itemRange.EndIndex);

                if (maxOffset < 0)
                {
                    for (int j = 0; j >= maxOffset; j--)
                    {
                        if (object.Equals(sourceItems.GetItemAt(startIndex), item))
                        {
                            if (j != 0)
                            {
                                SelectionRange newItemRange = new SelectionRange(itemRange.StartIndex + j, itemRange.EndIndex + j);
                                m_list[i] = new SelectionCellRangeWithItems(newItemRange, items, cellRangeWithItems.ColumnRange);
                            }

                            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 newItemRange = new SelectionRange(itemRange.StartIndex + j, itemRange.EndIndex + j);
                                m_list[i] = new SelectionCellRangeWithItems(newItemRange, items, cellRangeWithItems.ColumnRange);
                            }

                            break;
                        }

                        startIndex++;

                        if (startIndex >= sourceItemCount)
                        {
                            break;
                        }
                    }
                }
            }
        }
 public bool UnselectItems( DataGridContext dataGridContext, SelectionRangeWithItems rangeWithItems )
 {
   SelectionChanger selectionChanger = this.GetSelectionChanger( dataGridContext );
   return selectionChanger.UnselectItems( rangeWithItems );
 }
 internal SelectionRangeWithItemsWrapper(SelectionRangeWithItems value, int index)
 {
     m_value = value;
     m_index = index;
 }
        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 static void UpdateSelectionRangeWithItemsFromAdd(
            DataGridContext dataGridContext,
            SelectionRangeWithItems newRangeWithItems,
            ref SelectionRangeWithItems lastRangeWithItems)
        {
            // Only work for adding at the end of an existing range.

            object[] newRangeItems = newRangeWithItems.Items;

            if (((dataGridContext == null) ||
                 ((dataGridContext.ItemsSourceCollection == null) && (newRangeItems == null)) ||
                 (dataGridContext.ItemsSourceCollection is DataGridVirtualizingCollectionViewBase)))
            {
                lastRangeWithItems = new SelectionRangeWithItems(
                    new SelectionRange(lastRangeWithItems.Range.StartIndex, newRangeWithItems.Range.EndIndex),
                    null);

                return;
            }

            object[] rangeToUpdateItems = lastRangeWithItems.Items;
            object[] newItems;
            int      newItemsStartPosition;

            if (newRangeWithItems == lastRangeWithItems)
            {
                if (newRangeItems != null)
                {
                    return;
                }

                newItemsStartPosition = 0;
                newItems = new object[lastRangeWithItems.Length];
            }
            else
            {
                newItemsStartPosition = lastRangeWithItems.Length;
                newItems = new object[lastRangeWithItems.Length + newRangeWithItems.Length];
                Array.Copy(rangeToUpdateItems, newItems, newItemsStartPosition);
            }

            CollectionView items = (dataGridContext == null) ? null : dataGridContext.Items;
            int            rangeToUpdateStartIndex = lastRangeWithItems.Range.StartIndex;
            int            rangeToUpdateEndIndex   = lastRangeWithItems.Range.EndIndex;
            int            newRangeStartIndex      = newRangeWithItems.Range.StartIndex;
            int            newRangeEndIndex        = newRangeWithItems.Range.EndIndex;

            // If new range have no items set, found the items and set it.
            if (newRangeItems == null)
            {
                if (newRangeEndIndex > newRangeStartIndex)
                {
                    for (int i = newRangeStartIndex; i <= newRangeEndIndex; i++)
                    {
                        newItems[newItemsStartPosition] = items.GetItemAt(i);
                        newItemsStartPosition++;
                    }
                }
                else
                {
                    for (int i = newRangeStartIndex; i >= newRangeEndIndex; i--)
                    {
                        newItems[newItemsStartPosition] = items.GetItemAt(i);
                        newItemsStartPosition++;
                    }
                }
            }
            else
            {
                for (int i = 0; i < newRangeItems.Length; i++)
                {
                    newItems[newItemsStartPosition] = newRangeItems[i];
                    newItemsStartPosition++;
                }
            }

            lastRangeWithItems = new SelectionRangeWithItems(
                new SelectionRange(rangeToUpdateStartIndex, newRangeEndIndex),
                newItems);
        }
    public void UpdateSelectionAfterSourceDataItemRemoved( NotifyCollectionChangedEventArgs e )
    {
      int oldStartingIndex = e.OldStartingIndex;
      IList removedItemsList = e.OldItems;
      int removedItemsCount = removedItemsList.Count;

      m_sourceChanges.Add( new SourceChangeInfo( e.Action, oldStartingIndex, removedItemsCount, removedItemsList ) );

      if( oldStartingIndex == -1 )
      {
        foreach( object item in removedItemsList )
        {
          SelectionRangeWithItems rangeWithItemsToRemove = new SelectionRangeWithItems( SelectionRange.Empty, new object[] { item } );

          m_itemsToSelect.Remove( rangeWithItemsToRemove );
          m_itemsToUnselect.Remove( rangeWithItemsToRemove );

          SelectionCellRangeWithItems cellRangeWithItemsToRemove = new SelectionCellRangeWithItems(
            SelectionRange.Empty, new object[] { item }, new SelectionRange( 0, int.MaxValue - 1 ) );

          m_cellsToSelect.Remove( cellRangeWithItemsToRemove );
          m_cellsToUnselect.Remove( cellRangeWithItemsToRemove );
        }

        // Seek out in a max range of removedItemsCount the new position for actually selected item.
        m_itemsToSelect.OffsetIndexBasedOnSourceNewIndex( -removedItemsCount );
        m_itemsToUnselect.OffsetIndexBasedOnSourceNewIndex( -removedItemsCount );
        m_cellsToSelect.OffsetIndexBasedOnSourceNewIndex( -removedItemsCount );
        m_cellsToUnselect.OffsetIndexBasedOnSourceNewIndex( -removedItemsCount );
      }
      else
      {
        SelectionRange itemRange = new SelectionRange( oldStartingIndex, oldStartingIndex + removedItemsCount - 1 );
        SelectionRangeWithItems rangeWithItemsToRemove = new SelectionRangeWithItems( itemRange, null );
        m_itemsToSelect.Remove( rangeWithItemsToRemove );
        m_itemsToUnselect.Remove( rangeWithItemsToRemove );
        m_itemsToSelect.OffsetIndex( oldStartingIndex, -removedItemsCount );
        m_itemsToUnselect.OffsetIndex( oldStartingIndex, -removedItemsCount );

        SelectionCellRangeWithItems cellRangeWithItemsToRemove = new SelectionCellRangeWithItems(
          itemRange, null, new SelectionRange( 0, int.MaxValue - 1 ) );

        m_cellsToSelect.Remove( cellRangeWithItemsToRemove );
        m_cellsToUnselect.Remove( cellRangeWithItemsToRemove );
        m_cellsToSelect.OffsetIndex( oldStartingIndex, -removedItemsCount );
        m_cellsToUnselect.OffsetIndex( oldStartingIndex, -removedItemsCount );
      }
    }
    public bool SelectItems( SelectionRangeWithItems rangeWithItems )
    {
      SelectionRange range = rangeWithItems.Range;

      if( !( m_owner.ItemsSourceCollection is DataGridVirtualizingCollectionViewBase ) )
      {
        if( range.IsEmpty )
        {
          foreach( object item in rangeWithItems.Items )
          {
            if( !m_toDeferSelect.Contains( item ) )
              m_toDeferSelect.Add( item );
          }

          return false;
        }
      }
      else
      {
        if( range.IsEmpty )
          throw new ArgumentException( "rangeWithItems.Range can't be empty when we are using a DataGridVirtualizingCollectionView", "rangeWithItems" );
      }

      if( rangeWithItems.Length == 1 )
      {
        if( !m_itemsToUnselect.Remove( rangeWithItems ) )
        {
          if( m_owner.SelectedItemsStore.Contains( rangeWithItems ) )
            return false;

          if( m_itemsToSelect.Contains( range ) )
            return false;

          this.m_itemsToSelect.Add( rangeWithItems );
        }

        return true;
      }
      else
      {
        bool selectionChanged = m_itemsToUnselect.Remove( rangeWithItems );

        SelectedItemsStorage tempStorage = new SelectedItemsStorage( m_owner, 8 );
        tempStorage.Add( rangeWithItems );

        // Remove the currently selected item from the new range to select
        foreach( SelectionRangeWithItems existingSelectionRangeWithItems in m_owner.SelectedItemsStore )
        {
          tempStorage.Remove( existingSelectionRangeWithItems );
        }

        // Remove the pending item to be selected from the new range to select
        foreach( SelectionRangeWithItems existingSelectionRangeWithItems in m_itemsToSelect )
        {
          tempStorage.Remove( existingSelectionRangeWithItems );
        }

        if( tempStorage.Count > 0 )
        {
          selectionChanged = true;

          foreach( SelectionRangeWithItems rangeWithItemsToAdd in tempStorage )
          {
            m_itemsToSelect.Add( rangeWithItemsToAdd );
          }
        }

        return selectionChanged;
      }
    }
    public bool SelectJustThisItem( int itemIndex, object item )
    {
      bool selectionDone = true;
      m_toDeferSelect.Clear();

      SelectionRangeWithItems rangeWithItemsToSelect = new SelectionRangeWithItems( itemIndex, item );
      SelectionRange range = rangeWithItemsToSelect.Range;

      if( m_itemsToSelect.Contains( range ) )
        selectionDone = false;

      m_itemsToSelect.Clear();
      SelectedItemsStorage selectedItemsInChange = m_owner.SelectedItemsStore;

      if( selectedItemsInChange.Contains( range ) )
      {
        if( !m_itemsToUnselect.Contains( range ) )
          selectionDone = false;

        m_itemsToUnselect.Clear();

        foreach( SelectionRangeWithItems selectedRangeWithItems in selectedItemsInChange )
        {
          m_itemsToUnselect.Add( selectedRangeWithItems );
        }

        m_itemsToUnselect.Remove( rangeWithItemsToSelect );
      }
      else
      {
        m_itemsToSelect.Add( rangeWithItemsToSelect );
        m_itemsToUnselect.Clear();

        foreach( SelectionRangeWithItems selectedRangeWithItems in selectedItemsInChange )
        {
          m_itemsToUnselect.Add( selectedRangeWithItems );
        }
      }

      this.UnselectAllCells();
      return selectionDone;
    }
        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 void Visit(DataGridContext sourceContext, int startSourceDataItemIndex, int endSourceDataItemIndex, ref bool stopVisit)
        {
            SelectionManager selectionChangerManager = sourceContext.DataGridControl.SelectionChangerManager;

            if (m_selectedColumns != null)
            {
                int columnCount = sourceContext.Columns.Count;

                if (columnCount == 0)
                {
                    return;
                }

                SelectionRange contextColumnMaxRange = new SelectionRange(0, columnCount - 1);

                for (int i = 0; i < m_selectedColumns.Length; i++)
                {
                    SelectionRange selectionRange             = m_selectedColumns[i];
                    SelectionRange intersectionSelectionRange = selectionRange.Intersect(contextColumnMaxRange);

                    if (intersectionSelectionRange.IsEmpty)
                    {
                        continue;
                    }

#if DEBUG
                    string action = (m_unselect) ? "Removing" : "Adding";
                    Debug.WriteLine("Selection : " + action + " cell : (" + startSourceDataItemIndex.ToString() + " - " + endSourceDataItemIndex.ToString() + ") - ("
                                    + intersectionSelectionRange.StartIndex.ToString() + " - " + intersectionSelectionRange.EndIndex.ToString() + ")");
#endif

                    var cellRange = new SelectionCellRangeWithItems(new SelectionRange(startSourceDataItemIndex, endSourceDataItemIndex), null, intersectionSelectionRange);

                    if (m_unselect)
                    {
                        selectionChangerManager.UnselectCells(sourceContext, cellRange);
                    }
                    else
                    {
                        selectionChangerManager.SelectCells(sourceContext, cellRange);
                    }
                }
            }
            else
            {
#if DEBUG
                string action = (m_unselect) ? "Removing" : "Adding";
                Debug.WriteLine("Selection : " + action + " Adding item : " + startSourceDataItemIndex.ToString() + " - " + endSourceDataItemIndex.ToString());
#endif
                var itemRange = new SelectionRangeWithItems(new SelectionRange(startSourceDataItemIndex, endSourceDataItemIndex), null);

                if (m_unselect)
                {
                    selectionChangerManager.UnselectItems(sourceContext, itemRange);
                }
                else
                {
                    selectionChangerManager.SelectItems(sourceContext, itemRange);
                }
            }
        }
    public int Add( SelectionRangeWithItems rangeWithItems )
    {
      Debug.Assert( !this.Contains( rangeWithItems.Range ) );

      m_itemsCount += rangeWithItems.Length;
      int count = m_list.Count;

      if( count > 0 )
      {
        int lastIndex = count - 1;
        SelectionRangeWithItems lastRangeWithItems = m_list[ lastIndex ];
        SelectionRange lastRange = lastRangeWithItems.Range;

        if( ( lastRange.EndIndex + 1 ) == rangeWithItems.Range.StartIndex )
        {
          Debug.Assert( rangeWithItems.Range.EndIndex > lastRange.EndIndex );

          SelectedItemsStorage.UpdateSelectionRangeWithItemsFromAdd(
            m_dataGridContext, rangeWithItems, ref lastRangeWithItems );

          m_list[ lastIndex ] = lastRangeWithItems;
          return lastIndex;
        }
        else if( ( lastRange.EndIndex - 1 ) == rangeWithItems.Range.StartIndex )
        {
          Debug.Assert( rangeWithItems.Range.EndIndex < lastRange.EndIndex );

          SelectedItemsStorage.UpdateSelectionRangeWithItemsFromAdd(
            m_dataGridContext, rangeWithItems, ref lastRangeWithItems );

          m_list[ lastIndex ] = lastRangeWithItems;
          return lastIndex;
        }
      }

      SelectedItemsStorage.UpdateSelectionRangeWithItemsFromAdd(
        m_dataGridContext, rangeWithItems, ref rangeWithItems );

      m_list.Add( rangeWithItems );
      return m_list.Count - 1;
    }
    public void UpdateSelectionAfterSourceCollectionChanged( DataGridContext dataGridContext, NotifyCollectionChangedEventArgs e )
    {
      switch( e.Action )
      {
        case NotifyCollectionChangedAction.Replace:
          {
            // When we get a replace with the same instance, we just have nothing to do.
            if( ( e.NewItems.Count == 1 ) && ( e.OldItems.Count == 1 ) && ( e.OldItems[ 0 ] == e.NewItems[ 0 ] ) )
              break;

            this.Begin();

            try
            {
              // This is done to force the SelectionChangerManager to call the DataGridControl's
              // DataGridContext UpdatePublicSelectionProperties method wheter or not
              // there is any changes to the selection.  This is usefull when resetting due to a Sort operation for instance.
              this.EnsureRootSelectedItemAndSelectedIndex();

              SelectionChanger selectionChanger = this.GetSelectionChanger( dataGridContext );
              selectionChanger.UpdateSelectionAfterSourceDataItemReplaced( e );
            }
            finally
            {
              this.End( true, false, true );
            }

            break;
          }

        case NotifyCollectionChangedAction.Add:
          {
            this.Begin();

            try
            {
              // This is done to force the SelectionChangerManager to call the DataGridControl's
              // DataGridContext UpdatePublicSelectionProperties method wheter or not
              // there is any changes to the selection.  This is usefull when resetting due to a Sort operation for instance.
              this.EnsureRootSelectedItemAndSelectedIndex();

              m_rangeSelectionItemStartAnchor = -1;
              m_rangeSelectionColumnStartAnchor = -1;
              SelectionChanger selectionChanger = this.GetSelectionChanger( dataGridContext );
              selectionChanger.UpdateSelectionAfterSourceDataItemAdded( e );
            }
            finally
            {
              this.End( true, false, true );
            }

            break;
          }

        case NotifyCollectionChangedAction.Remove:
          {
            this.Begin();

            try
            {
              // This is done to force the SelectionChangerManager to call the DataGridControl's
              // DataGridContext UpdatePublicSelectionProperties method wheter or not
              // there is any changes to the selection.  This is usefull when resetting due to a Sort operation for instance.
              this.EnsureRootSelectedItemAndSelectedIndex();

              m_rangeSelectionItemStartAnchor = -1;
              m_rangeSelectionColumnStartAnchor = -1;
              SelectionChanger selectionChanger = this.GetSelectionChanger( dataGridContext );
              selectionChanger.UpdateSelectionAfterSourceDataItemRemoved( e );
            }
            finally
            {
              this.End( true, false, true );
            }

            break;
          }

        case NotifyCollectionChangedAction.Move:
        case NotifyCollectionChangedAction.Reset:
          {
            this.Begin();

            try
            {
              // This is done to force the SelectionChangerManager to call the DataGridControl's
              // DataGridContext UpdatePublicSelectionProperties method wheter or not
              // there is any changes to the selection.  This is usefull when resetting due to a Sort operation for instance.
              this.EnsureRootSelectedItemAndSelectedIndex();

              m_rangeSelectionItemStartAnchor = -1;
              m_rangeSelectionColumnStartAnchor = -1;

              SelectedItemsStorage selectedItemsStorage = dataGridContext.SelectedItemsStore;
              int selectedItemsCount = selectedItemsStorage.Count;
              SelectedCellsStorage selectedCellsStorage = dataGridContext.SelectedCellsStore;
              int selectedCellsCount = selectedCellsStorage.Count;
              SelectionChanger selectionChanger = this.GetSelectionChanger( dataGridContext );

              int newItemCount = dataGridContext.Items.Count;
              SelectionRange maxItemRange;

              if( newItemCount == 0 )
              {
                maxItemRange = SelectionRange.Empty;
              }
              else
              {
                maxItemRange = new SelectionRange( 0, newItemCount - 1 );
              }

              if( selectedItemsCount > 0 )
              {
                selectionChanger.UnselectAllItems();

                for( int i = 0; i < selectedItemsCount; i++ )
                {
                  SelectionRangeWithItems rangeWithItems = selectedItemsStorage[ i ];
                  object[] items = rangeWithItems.Items;

                  if( items == null )
                  {
                    SelectionRange itemRange = rangeWithItems.Range;
                    SelectionRange rangeIntersection = itemRange.Intersect( maxItemRange );

                    if( rangeIntersection != itemRange )
                    {
                      if( rangeIntersection.IsEmpty )
                        continue;

                      rangeWithItems = new SelectionRangeWithItems( rangeIntersection, null );
                    }

                    selectionChanger.SelectItems( rangeWithItems );
                  }
                  else
                  {
                    CollectionView sourceItems = dataGridContext.Items;
                    int itemsCount = items.Length;
                    SelectionRange range = rangeWithItems.Range;

                    for( int j = 0; j < itemsCount; j++ )
                    {
                      object item = items[ j ];
                      int index = sourceItems.IndexOf( item );

                      if( index != -1 )
                      {
                        selectionChanger.SelectItems( new SelectionRangeWithItems( index, item ) );
                      }
                    }
                  }
                }
              }

              if( selectedCellsCount > 0 )
              {
                selectionChanger.UnselectAllCells();

                for( int i = 0; i < selectedCellsCount; i++ )
                {
                  SelectionCellRangeWithItems cellRangeWithItems = selectedCellsStorage[ i ];
                  SelectionRangeWithItems itemRangeWithItems = cellRangeWithItems.ItemRangeWithItems;
                  object[] items = itemRangeWithItems.Items;

                  if( items == null )
                  {
                    SelectionRange itemRange = itemRangeWithItems.Range;
                    SelectionRange itemRangeIntersection = itemRange.Intersect( maxItemRange );

                    if( itemRangeIntersection != itemRange )
                    {
                      if( itemRangeIntersection.IsEmpty )
                        continue;

                      cellRangeWithItems = new SelectionCellRangeWithItems( itemRangeIntersection, null, cellRangeWithItems.ColumnRange );
                    }

                    selectionChanger.SelectCells( cellRangeWithItems );
                  }
                  else
                  {
                    CollectionView sourceItems = dataGridContext.Items;
                    int itemsCount = items.Length;
                    SelectionRange itemRange = cellRangeWithItems.ItemRange;

                    for( int j = 0; j < itemsCount; j++ )
                    {
                      object item = items[ j ];
                      int index = sourceItems.IndexOf( item );

                      if( index != -1 )
                      {
                        selectionChanger.SelectCells( new SelectionCellRangeWithItems(
                          new SelectionRange( index ), new object[] { item }, cellRangeWithItems.ColumnRange ) );
                      }
                    }
                  }
                }
              }
            }
            finally
            {
              this.End( true, false, true );
            }

            break;
          }
      }
    }
    public void Insert( int index, SelectionRangeWithItems rangeWithItems )
    {
      Debug.Assert( !this.Contains( rangeWithItems.Range ) );
      m_itemsCount += rangeWithItems.Length;

      SelectedItemsStorage.UpdateSelectionRangeWithItemsFromAdd(
        m_dataGridContext, rangeWithItems, ref rangeWithItems );

      m_list.Insert( index, rangeWithItems );
    }
Exemple #38
0
        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 bool UnselectItems(SelectionRangeWithItems rangeWithItems)
        {
            if (!(m_owner.ItemsSourceCollection is DataGridVirtualizingCollectionViewBase))
            {
                if (m_toDeferSelect.Count > 0)
                {
                    foreach (object item in rangeWithItems.Items)
                    {
                        m_toDeferSelect.Remove(item);
                    }
                }
            }

            SelectionRange range = rangeWithItems.Range;

            if (range.IsEmpty)
            {
                // We have no index we have to remove based on item
                bool selectionChanged = false;

                List <SelectionRangeWithItems> itemsRangeToRemove = new List <SelectionRangeWithItems>();
                List <object> itemsToUnselect = new List <object>(rangeWithItems.Items);
                int           count           = itemsToUnselect.Count;

                for (int i = count - 1; i >= 0; i--)
                {
                    object itemToUnselect = itemsToUnselect[i];
                    bool   selectionAdded = false;

                    foreach (SelectionRangeWithItems existingSelectionRangeWithItems in m_itemsToSelect)
                    {
                        int index = Array.IndexOf(existingSelectionRangeWithItems.Items, itemToUnselect);

                        if (index > -1)
                        {
                            selectionAdded = true;

                            itemsRangeToRemove.Add(
                                new SelectionRangeWithItems(
                                    existingSelectionRangeWithItems.Range.GetIndexFromItemOffset(index),
                                    itemToUnselect));
                        }
                    }

                    if (selectionAdded)
                    {
                        itemsToUnselect.RemoveAt(i);
                    }
                }

                // Remove the currently unselected item from the new range to select
                foreach (SelectionRangeWithItems itemRangeToRemove in itemsRangeToRemove)
                {
                    selectionChanged |= m_itemsToSelect.Remove(itemRangeToRemove);
                }

                count = itemsToUnselect.Count;

                for (int i = 0; i < count; i++)
                {
                    object itemToUnselect = itemsToUnselect[i];

                    foreach (SelectionRangeWithItems existingSelectionRangeWithItems in m_owner.SelectedItemsStore)
                    {
                        int index = Array.IndexOf(existingSelectionRangeWithItems.Items, itemToUnselect);

                        if (index >= 0)
                        {
                            index = existingSelectionRangeWithItems.Range.GetIndexFromItemOffset(index);

                            if (!m_itemsToUnselect.Contains(index))
                            {
                                selectionChanged = true;
                                m_itemsToUnselect.Add(new SelectionRangeWithItems(index, itemToUnselect));
                            }
                        }
                    }
                }

                return(selectionChanged);
            }

            if (range.Length == 1)
            {
                if (!m_itemsToSelect.Remove(rangeWithItems))
                {
                    if (!m_owner.SelectedItemsStore.Contains(range))
                    {
                        return(false);
                    }

                    if (m_itemsToUnselect.Contains(range))
                    {
                        return(false);
                    }

                    m_itemsToUnselect.Add(rangeWithItems);
                }

                return(true);
            }
            else
            {
                SelectedItemsStorage tempStorage = new SelectedItemsStorage(m_owner);
                tempStorage.Add(rangeWithItems);

                // Remove the currently selected item from the new range to select
                foreach (SelectionRangeWithItems existingSelectionRangeWithItems in m_itemsToSelect)
                {
                    if (!range.Intersect(existingSelectionRangeWithItems.Range).IsEmpty)
                    {
                        tempStorage.Remove(existingSelectionRangeWithItems);
                    }
                }

                bool selectionChanged = m_itemsToSelect.Remove(rangeWithItems);

                if (tempStorage.Count > 0)
                {
                    selectionChanged = true;

                    foreach (SelectionRangeWithItems rangeWithItemsToAdd in tempStorage)
                    {
                        Debug.Assert(!m_itemsToUnselect.Contains(rangeWithItemsToAdd.Range));
                        m_itemsToUnselect.Add(rangeWithItemsToAdd);
                    }
                }

                return(selectionChanged);
            }
        }
        public bool SelectItems(SelectionRangeWithItems rangeWithItems)
        {
            SelectionRange range = rangeWithItems.Range;

            if (!(m_owner.ItemsSourceCollection is DataGridVirtualizingCollectionViewBase))
            {
                if (range.IsEmpty)
                {
                    foreach (object item in rangeWithItems.Items)
                    {
                        if (!m_toDeferSelect.Contains(item))
                        {
                            m_toDeferSelect.Add(item);
                        }
                    }

                    return(false);
                }
            }
            else
            {
                if (range.IsEmpty)
                {
                    throw new ArgumentException("rangeWithItems.Range can't be empty when we are using a DataGridVirtualizingCollectionView", "rangeWithItems");
                }
            }

            if (rangeWithItems.Length == 1)
            {
                if (!m_itemsToUnselect.Remove(rangeWithItems))
                {
                    if (m_owner.SelectedItemsStore.Contains(rangeWithItems))
                    {
                        return(false);
                    }

                    if (m_itemsToSelect.Contains(range))
                    {
                        return(false);
                    }

                    this.m_itemsToSelect.Add(rangeWithItems);
                }

                return(true);
            }
            else
            {
                bool selectionChanged = m_itemsToUnselect.Remove(rangeWithItems);

                SelectedItemsStorage tempStorage = new SelectedItemsStorage(m_owner);
                tempStorage.Add(rangeWithItems);

                // Remove the currently selected item from the new range to select
                foreach (SelectionRangeWithItems existingSelectionRangeWithItems in m_owner.SelectedItemsStore)
                {
                    tempStorage.Remove(existingSelectionRangeWithItems);
                }

                // Remove the pending item to be selected from the new range to select
                foreach (SelectionRangeWithItems existingSelectionRangeWithItems in m_itemsToSelect)
                {
                    tempStorage.Remove(existingSelectionRangeWithItems);
                }

                if (tempStorage.Count > 0)
                {
                    selectionChanged = true;

                    foreach (SelectionRangeWithItems rangeWithItemsToAdd in tempStorage)
                    {
                        m_itemsToSelect.Add(rangeWithItemsToAdd);
                    }
                }

                return(selectionChanged);
            }
        }
    private bool SetIsSelectedOnDataRow( Dictionary<int, DataRow> realizedDataRows, SelectionRangeWithItems rangeWithItems, bool selected )
    {
      int rangeLength = rangeWithItems.Length;
      object[] rangeItems = rangeWithItems.Items;
      bool selectionChanged = false;

      if( rangeItems != null )
      {
        for( int i = 0; i < rangeLength; i++ )
        {
          DataRow rangeItemAsDataRow = rangeItems[ i ] as DataRow;

          if( rangeItemAsDataRow != null )
          {
            selectionChanged = true;
            rangeItemAsDataRow.SetIsSelected( selected );
          }
          else
          {
            // We take for granted that no item will be a DataRow
            break;
          }
        }
      }

      return selectionChanged;
    }
        private bool SetIsSelectedOnDataRow(Dictionary <int, DataRow> realizedDataRows, SelectionRangeWithItems rangeWithItems, bool selected)
        {
            int rangeLength = rangeWithItems.Length;

            object[] rangeItems       = rangeWithItems.Items;
            bool     selectionChanged = false;

            if (rangeItems != null)
            {
                for (int i = 0; i < rangeLength; i++)
                {
                    DataRow rangeItemAsDataRow = rangeItems[i] as DataRow;

                    if (rangeItemAsDataRow != null)
                    {
                        selectionChanged = true;
                        rangeItemAsDataRow.SetIsSelected(selected);
                    }
                    else
                    {
                        // We take for granted that no item will be a DataRow
                        break;
                    }
                }
            }

            return(selectionChanged);
        }
    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 Contains( SelectionRangeWithItems rangeWithItemsToCompare )
    {
      int count = m_list.Count;
      SelectionRange rangeToCompare = rangeWithItemsToCompare.Range;

      for( int i = 0; i < count; i++ )
      {
        SelectionRangeWithItems rangeWithItem = m_list[ i ];
        SelectionRange rangeIntersection = rangeWithItem.Range.Intersect( rangeToCompare );

        if( !rangeIntersection.IsEmpty )
        {
          if( rangeWithItemsToCompare.IsItemsEqual( rangeIntersection, rangeWithItem ) )
            return true;
        }
      }

      return false;
    }
        private bool FindItem(int index, DataGridContext dataGridContext, int itemsCount, out SelectionRangeWithItems range, out int offset)
        {
            var rangesCount = m_storage.Count;

            range  = SelectionRangeWithItems.Empty;
            offset = index;

            for (int i = 0; i < rangesCount; i++)
            {
                if (offset < 0)
                {
                    break;
                }

                range = m_storage[i];
                var length = range.Length;

                if (offset < length)
                {
                    var startAt = range.Range.StartIndex;
                    var endAt   = range.Range.EndIndex;

                    if (startAt > endAt)
                    {
                        if (startAt - offset >= itemsCount)
                        {
                            break;
                        }
                    }
                    else
                    {
                        if (startAt + offset >= itemsCount)
                        {
                            break;
                        }
                    }

                    Debug.Assert((offset >= 0) && (offset < length));

                    return(true);
                }
                else
                {
                    offset -= length;
                }
            }

            return(false);
        }
    public bool IsItemsEqual( SelectionRange rangeIntersection, SelectionRangeWithItems rangeWithItemsToCompare )
    {
      object[] itemsToCompare = rangeWithItemsToCompare.m_items;

      if( ( m_items == null ) || ( itemsToCompare == null ) )
        return true;

      SelectionRange rangeToCompare = rangeWithItemsToCompare.Range;
      int startIndex = Math.Min( rangeIntersection.StartIndex, rangeIntersection.EndIndex );
      int itemIndex1 = Math.Abs( startIndex - m_range.StartIndex );
      int itemIndex2 = Math.Abs( startIndex - rangeToCompare.StartIndex );
      bool inversedRange1 = m_range.StartIndex > m_range.EndIndex;
      bool inversedRange2 = rangeToCompare.StartIndex > rangeToCompare.EndIndex;
      int count = rangeIntersection.Length;

      for( int i = 0; i < count; i++ )
      {
        if( !object.Equals( m_items[ itemIndex1 ], itemsToCompare[ itemIndex2 ] ) )
          return false;

        itemIndex1 = inversedRange1 ? itemIndex1 - 1 : itemIndex1 + 1;
        itemIndex2 = inversedRange2 ? itemIndex2 - 1 : itemIndex2 + 1;
      }

      return true;
    }    
    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;
    }