コード例 #1
0
    private void HandleItemMoveRemoveReplaceHelper( ItemsGeneratorNode node, NotifyCollectionChangedEventArgs e, int nodeIndex )
    {
      node.AdjustItemCount( e.NewItems.Count );
      node.AdjustLeafCount( e.NewItems.Count );

      this.IncrementCurrentGenerationCount();

      //this is used to notify any Master Generator that it must update its content's status (UpdateGenPosToIndexList)
      this.SendAddEvent( new GeneratorPosition( -1, 1 ), nodeIndex + e.NewStartingIndex, e.NewItems.Count );
    }
コード例 #2
0
    private void RemoveDetails( ItemsGeneratorNode node, int nodeStartIndex, int nodeEndIndex, int replaceCount )
    {
      if( ( node.Details == null ) || ( node.Details.Count == 0 ) )
        return;

      int removeCount = nodeEndIndex - nodeStartIndex + 1 - replaceCount;
      //Note: If a replace was invoked, replace count will be greater than 0, and will be used to properly re-offset the 
      //details beyond the initial remove range.

      //Note2: for the case of a move or remove, the replace count must remain 0, so that the other details are correctly offseted.

      //first, create an array that will contain the keys for all the expanded details from the ItemsGeneratorNode
      int[] keys = new int[ node.Details.Count ];
      node.Details.Keys.CopyTo( keys, 0 );

      //sort the array, this will prevent any operation that will duplicate keys in the dictionary.
      Array.Sort<int>( keys );

      //cycle through all of the old items
      int countDetailsRemoved = 0;
      foreach( int key in keys )
      {
        //if the key is below the remove range, do not do anything with the dictionary entry

        //If the key match the remove range, remove the dictionary entry ( clear and queue remap )
        if( ( key >= nodeStartIndex ) && ( key <= nodeEndIndex ) )
        {
          List<DetailGeneratorNode> details;
          if( node.Details.TryGetValue( key, out details ) )
          {
            //sum them
            foreach( DetailGeneratorNode detailNode in details )
            {
              countDetailsRemoved += detailNode.ItemCount;
            }
            details.Clear(); //note: detail generators will be "closed" by another section of code (Remap floating details).

#if LOG
            Log.WriteLine( this, "details.Remove - IN" + node.GetHashCode().ToString() + " - Di" + key.ToString() );
#endif

            node.Details.Remove( key );

            if( node.Details.Count == 0 )
            {
              node.Details = null;
            }
          }
          else
          {
            //Key not found in the dictionary, something wrong is going on.
            throw new DataGridInternalException();
          }
        }
        //If the key is above the remove range, re-key it appropriatly.
        else if( key > nodeEndIndex )
        {
          List<DetailGeneratorNode> details;
          if( node.Details.TryGetValue( key, out details ) )
          {
#if LOG
            Log.WriteLine( this, "details.offset for remove - IN" + node.GetHashCode().ToString() + "- Di" + key.ToString() + " - new Di" + ( key - removeCount ).ToString() );
#endif
            node.Details.Remove( key );
            node.Details.Add( key - removeCount, details );
          }
          else
          {
            //Key not found in the dictionary, something wrong is going on.
            throw new DataGridInternalException();
          }
        }
      }

      //if some details have been "disconnected"
      if( countDetailsRemoved > 0 )
      {
        node.AdjustItemCount( -countDetailsRemoved );
      }
    }
コード例 #3
0
    private void HandleItemRemoveMoveReplace( ItemsGeneratorNode node, NotifyCollectionChangedEventArgs e )
    {
      GeneratorNodeHelper nodeHelper = new GeneratorNodeHelper( node, 0, 0 ); //index not important for now.
      nodeHelper.ReverseCalculateIndex();

      node.AdjustItemCount( -e.OldItems.Count );
      node.AdjustLeafCount( -e.OldItems.Count );

      int nodeStartIndex = e.OldStartingIndex;
      int nodeEndIndex = nodeStartIndex + e.OldItems.Count - 1;
      int detailCountToRemove = CustomItemContainerGenerator.ComputeDetailsCount( node, nodeStartIndex, nodeEndIndex );
      int detailCountBeforeRemovedItems = 0;
      if( nodeStartIndex > 0 )
      {
        detailCountBeforeRemovedItems = CustomItemContainerGenerator.ComputeDetailsCount( node, 0, nodeStartIndex - 1 );
      }

      int startIndex = nodeHelper.Index + e.OldStartingIndex + detailCountBeforeRemovedItems;
      int endIndex = startIndex + detailCountToRemove + e.OldItems.Count - 1;

      int removeCount = e.OldItems.Count + detailCountToRemove;
      int replaceCount = ( e.Action == NotifyCollectionChangedAction.Replace ) ? e.NewItems.Count : 0;

      // *** RemoveDetails must be done before GeneratorPositionFromIndex, since GeneratorPositionFromIndex will indirectly do a RemapFloatingDetails
      // *** that will cause the index to already be rectified and make a double rectification to occurs.

      //Remove the details from the ItemsGeneratorNode and re-index the other details appropriatly.
      this.RemoveDetails( node, nodeStartIndex, nodeEndIndex, replaceCount );

      GeneratorPosition removeGenPos = this.GeneratorPositionFromIndex( startIndex );

      //Try to remap the old item for detail remapping (will do nothing if item has no details )
      foreach( object oldItem in e.OldItems )
      {
        this.QueueDetailItemForRemapping( oldItem );
      }

      //if the node is totally expanded
      if( node.IsComputedExpanded )
      {
        List<DependencyObject> removedContainers = new List<DependencyObject>();
        int genRemCount = this.RemoveGeneratedItems( startIndex, endIndex, removedContainers );

        this.IncrementCurrentGenerationCount();

        this.SendRemoveEvent( removeGenPos, startIndex, removeCount, genRemCount, removedContainers );
      }

      //then, based on the action that was performed (move, replace or remove)
      switch( e.Action )
      {
        case NotifyCollectionChangedAction.Move:
          this.OffsetDetails( node, e.NewStartingIndex, e.NewItems.Count );
          this.HandleItemMoveRemoveReplaceHelper( node, e, nodeHelper.Index );
          break;

        case NotifyCollectionChangedAction.Replace:
          this.HandleItemMoveRemoveReplaceHelper( node, e, nodeHelper.Index );
          break;

        case NotifyCollectionChangedAction.Remove:
          // Do nothing!
          break;

        case NotifyCollectionChangedAction.Add:
        case NotifyCollectionChangedAction.Reset:
        default:
          throw new DataGridInternalException();
      }

    }