public GeneratorNode CreateItemsGeneratorNode(
            IList collection,
            GeneratorNode parent,
            GeneratorNode previous,
            GeneratorNode next)
        {
            Debug.Assert(collection != null, "collection cannot be null for CreateItemsGeneratorNode()");

            INotifyCollectionChanged notifyCollection = collection as INotifyCollectionChanged;

            Debug.Assert(notifyCollection != null, "collection must be a INotifyCollectionChanged for CreateItemsGeneratorNode()");

            ItemCollection itemCollection = collection as ItemCollection;

            if (itemCollection != null)
            {
                DataGridCollectionView dgcv = itemCollection.SourceCollection as DataGridCollectionView;
                if (dgcv != null)
                {
                    collection = dgcv;
                }
            }

            ItemsGeneratorNode node = new ItemsGeneratorNode(collection, parent);

            this.SetupCollectionGeneratorNode(node, parent, previous, next);

            node.AdjustLeafCount(node.Items.Count);

            return(node);
        }
Esempio n. 2
0
        public GeneratorNode CreateItemsGeneratorNode(
            IList collection,
            GeneratorNode parent,
            GeneratorNode previous,
            GeneratorNode next,
            CustomItemContainerGenerator generator)
        {
            Debug.Assert(collection != null, "collection cannot be null for CreateItemsGeneratorNode()");
            Debug.Assert(generator != null);

            INotifyCollectionChanged notifyCollection = collection as INotifyCollectionChanged;

            Debug.Assert(notifyCollection != null, "collection must be a INotifyCollectionChanged for CreateItemsGeneratorNode()");

            //case 113904: If the item source for the ItemsGeneratorNode is an ItemCollection, then
            //check if the underlying SourceCollection is a DataGridCollectionView.
            //This particular exception case is there to handle messaging quirks in the case
            //of Master Detail edition. Refer to case for more details.
            ItemCollection itemCollection = collection as ItemCollection;

            if (itemCollection != null)
            {
                DataGridCollectionView dgcv = itemCollection.SourceCollection as DataGridCollectionView;
                if (dgcv != null)
                {
                    collection = dgcv;
                }
            }

            ItemsGeneratorNode node = new ItemsGeneratorNode(collection, parent);

            this.SetupCollectionGeneratorNode(node, parent, previous, next);


            node.AdjustLeafCount(node.Items.Count);

            return(node);
        }
    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 );
    }
    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();
      }

    }
    public GeneratorNode CreateItemsGeneratorNode(
      IList collection,
      GeneratorNode parent,
      GeneratorNode previous,
      GeneratorNode next,
      CustomItemContainerGenerator generator )
    {
      Debug.Assert( collection != null, "collection cannot be null for CreateItemsGeneratorNode()" );
      Debug.Assert( generator != null );

      INotifyCollectionChanged notifyCollection = collection as INotifyCollectionChanged;

      Debug.Assert( notifyCollection != null, "collection must be a INotifyCollectionChanged for CreateItemsGeneratorNode()" );

      ItemCollection itemCollection = collection as ItemCollection;
      if( itemCollection != null )
      {
        DataGridCollectionView dgcv = itemCollection.SourceCollection as DataGridCollectionView;
        if( dgcv != null )
        {
          collection = dgcv;
        }
      }

      ItemsGeneratorNode node = new ItemsGeneratorNode( collection, parent );

      this.SetupCollectionGeneratorNode( node, parent, previous, next );


      node.AdjustLeafCount( node.Items.Count );

      return node;
    }
    public GeneratorNode CreateItemsGeneratorNode(
      IList collection,
      GeneratorNode parent,
      GeneratorNode previous,
      GeneratorNode next,
      CustomItemContainerGenerator generator )
    {
      Debug.Assert( collection != null, "collection cannot be null for CreateItemsGeneratorNode()" );
      Debug.Assert( generator != null );

      INotifyCollectionChanged notifyCollection = collection as INotifyCollectionChanged;

      Debug.Assert( notifyCollection != null, "collection must be a INotifyCollectionChanged for CreateItemsGeneratorNode()" );

      //case 113904: If the item source for the ItemsGeneratorNode is an ItemCollection, then
      //check if the underlying SourceCollection is a DataGridCollectionView.
      //This particular exception case is there to handle messaging quirks in the case 
      //of Master Detail edition. Refer to case for more details.
      ItemCollection itemCollection = collection as ItemCollection;
      if( itemCollection != null )
      {
        DataGridCollectionView dgcv = itemCollection.SourceCollection as DataGridCollectionView;
        if( dgcv != null )
        {
          collection = dgcv;
        }
      }

      ItemsGeneratorNode node = new ItemsGeneratorNode( collection, parent );

      this.SetupCollectionGeneratorNode( node, parent, previous, next );


      node.AdjustLeafCount( node.Items.Count );

      return node;
    }