private void HandleHeaderFooterReplace( HeadersFootersGeneratorNode node, NotifyCollectionChangedEventArgs e )
    {
      //add immediately the number of new items to the "parent" node since the function call right below will remove the number of old items.
      node.AdjustItemCount( e.NewItems.Count );

      this.HandleHeaderFooterRemove( node, e );
    }
    private bool RemoveGeneratedItems( HeadersFootersGeneratorNode referenceNode, object referenceItem, IList<DependencyObject> removedContainers )
    {

      bool retval = false;

      //cycle through the list of generated items, and see if any items are generated between the indexes in the removed range.
      //start from the end so that removing an item will not cause the indexes to shift
      for( int i = m_genPosToNode.Count - 1; i >= 0; i-- )
      {
        GeneratorNode node = m_genPosToNode[ i ];

        //if the item is within the range removed
        if( node == referenceNode )
        {
          object item = m_genPosToItem[ i ];

          if( item.Equals( referenceItem ) )
          {
            DependencyObject container = m_genPosToContainer[ i ];
            removedContainers.Add( container );

            this.RemoveContainer( container, referenceItem );

            retval = true;

            this.GenPosArraysRemoveAt( i );

            break;
          }
        }
      }

      return retval;
    }
    private void HandleHeaderFooterRemove( HeadersFootersGeneratorNode node, NotifyCollectionChangedEventArgs e )
    {
      bool itemsRemoved = false;

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

      //if the node is totally expanded
      if( node.IsComputedExpanded )
      {
        GroupGeneratorNode parentGroup = node.Parent as GroupGeneratorNode;

        int removeGenPosIndex;
        int removeIndex;

        foreach( object item in e.OldItems )
        {
          object realItem = ( parentGroup != null )
                              ? new GroupHeaderFooterItem( parentGroup.CollectionViewGroup, item )
                              : item;


          removeGenPosIndex = m_genPosToItem.IndexOf( realItem );
          GeneratorPosition removeGenPos;
          // If the value is -1, it means the Header/Footer was not realized when the remove occured.
          if( removeGenPosIndex != -1 )
          {
            removeIndex = m_genPosToIndex[ removeGenPosIndex ];
            removeGenPos = new GeneratorPosition( removeGenPosIndex, 0 );
          }
          else
          {
            //Since there is no way to get the item's index from the list of generated items, then
            //compute it based on the node's index and the event args parameters.

            GeneratorNodeHelper nodeHelper = new GeneratorNodeHelper( node, 0, 0 );
            nodeHelper.ReverseCalculateIndex();

            removeIndex = nodeHelper.Index + e.OldStartingIndex;

            removeGenPos = this.GeneratorPositionFromIndex( removeIndex );
          }

          List<DependencyObject> removedContainers = new List<DependencyObject>();
          this.RemoveGeneratedItems( node, realItem, removedContainers );

          this.SendRemoveEvent( removeGenPos, removeIndex, 1, removedContainers.Count, removedContainers );
          itemsRemoved = true;
        }

        this.IncrementCurrentGenerationCount( itemsRemoved );
      }
    }
 private int GetStickyFooterCountForNode(
   HeadersFootersGeneratorNode footerNode,
   int footerNodeIndex )
 {
   return this.GetStickyFooterCountForNode( footerNode, footerNodeIndex, -1, false );
 }
    private int GetStickyFooterCountForNode(
      HeadersFootersGeneratorNode footerNode,
      int footerNodeIndex,
      int realizedIndex,
      bool isRealizedIndexPartOfHeaderNode )
    {
      int stickyFooterCount = 0;

      int footersNodeItemCount = footerNode.ItemCount;
      for( int i = footersNodeItemCount - 1; i >= 0; i-- )
      {
        if( ( isRealizedIndexPartOfHeaderNode )
            && ( footerNodeIndex + i < realizedIndex ) )
        {
          continue;
        }

        object item = footerNode.GetAt( i );

        GroupHeaderFooterItem? groupHeaderFooterItem = null;

        if( item is GroupHeaderFooterItem )
          groupHeaderFooterItem = ( GroupHeaderFooterItem )item;

        if( ( groupHeaderFooterItem != null )
          && ( !( groupHeaderFooterItem.Value.Group.IsBottomLevel ) || !this.IsGroupExpanded( groupHeaderFooterItem.Value.Group ) ) )
        {
          continue;
        }

        stickyFooterCount++;
      }

      return stickyFooterCount;
    }
 private List<StickyContainerGenerated> GenerateStickyFootersForNode(
   HeadersFootersGeneratorNode footerNode,
   int footerNodeIndex )
 {
   return this.GenerateStickyFootersForNode( footerNode, footerNodeIndex, -1, false );
 }
    private List<StickyContainerGenerated> GenerateStickyFootersForNode(
      HeadersFootersGeneratorNode footerNode,
      int footerNodeIndex,
      int realizedIndex,
      bool isRealizedIndexPartOfFooterNode )
    {
      List<StickyContainerGenerated> generatedStickyContainers = new List<StickyContainerGenerated>();

      int footersNodeItemCount = footerNode.ItemCount;

      // The container is already part of the footer.
      ICustomItemContainerGenerator generator = ( ICustomItemContainerGenerator )this;
      GeneratorPosition position = generator.GeneratorPositionFromIndex( footerNodeIndex + footersNodeItemCount - 1 );

      // In that case, the potential sticky containers are the requested one and bottom.
      using( generator.StartAt( position, GeneratorDirection.Backward, true ) )
      {
        for( int i = footersNodeItemCount - 1; i >= 0; i-- )
        {
          if( ( isRealizedIndexPartOfFooterNode )
              && ( footerNodeIndex + i < realizedIndex ) )
          {
            continue;
          }

          object item = footerNode.GetAt( i );

          GroupHeaderFooterItem? groupHeaderFooterItem = null;

          if( item is GroupHeaderFooterItem )
            groupHeaderFooterItem = ( GroupHeaderFooterItem )item;

          if( ( groupHeaderFooterItem != null )
            && ( !( groupHeaderFooterItem.Value.Group.IsBottomLevel ) || !this.IsGroupExpanded( groupHeaderFooterItem.Value.Group ) ) )
          {
            this.Skip();
            continue;
          }

          bool isNewlyRealized;
          DependencyObject stickyContainer = generator.GenerateNext( out isNewlyRealized );

          generatedStickyContainers.Add( new StickyContainerGenerated( stickyContainer, footerNodeIndex + i, isNewlyRealized ) );
        }
      }

      return generatedStickyContainers;
    }
    private void CleanHeadersFootersNotification( HeadersFootersGeneratorNode node )
    {
      var collection = node.Items as INotifyCollectionChanged;
      if( collection == null )
        return;

      try
      {
        var nodeList = m_headersFootersMapping[ collection ];
        nodeList.Remove( node );

        if( nodeList.Count == 0 )
        {
          CollectionChangedEventManager.RemoveListener( collection, this );
          m_headersFootersMapping.Remove( collection );
        }
      }
      catch( Exception e )
      {
        throw new DataGridInternalException( e.Message, e, this.DataGridControl );
      }
    }
    private List<StickyContainerGenerated> GenerateStickyHeadersForNode(
      HeadersFootersGeneratorNode headerNode,
      int headerNodeIndex,
      int realizedIndex,
      bool isRealizedIndexPartOfHeaderNode )
    {
      List<StickyContainerGenerated> generatedStickyContainers = new List<StickyContainerGenerated>();

      // The container is already part of the header.
      ICustomItemContainerGenerator generator = ( ICustomItemContainerGenerator )this;
      GeneratorPosition position = generator.GeneratorPositionFromIndex( headerNodeIndex );

      // In that case, the potential sticky containers are the requested one and up.
      using( generator.StartAt( position, GeneratorDirection.Forward, true ) )
      {
        for( int i = 0; i < headerNode.ItemCount; i++ )
        {
          // If the realized index represent the index of one of the HeaderNode
          // item, do not process
          if( ( isRealizedIndexPartOfHeaderNode )
              && ( headerNodeIndex + i > realizedIndex ) )
          {
            break;
          }

          object item = headerNode.GetAt( i );

          GroupHeaderFooterItem? groupHeaderFooterItem = null;

          if( item is GroupHeaderFooterItem )
            groupHeaderFooterItem = ( GroupHeaderFooterItem )item;

          if( ( groupHeaderFooterItem != null )
            && ( !( groupHeaderFooterItem.Value.Group.IsBottomLevel ) || !this.IsGroupExpanded( groupHeaderFooterItem.Value.Group ) ) )
          {
            this.Skip();
            continue;
          }

          bool isNewlyRealized;
          DependencyObject stickyContainer = generator.GenerateNext( out isNewlyRealized );

          generatedStickyContainers.Add( new StickyContainerGenerated( stickyContainer, headerNodeIndex + i, isNewlyRealized ) );
        }
      }

      return generatedStickyContainers;
    }
    private void ConfigureHeadersFootersNotification( INotifyCollectionChanged collection, HeadersFootersGeneratorNode node )
    {
      ICollection<HeadersFootersGeneratorNode> nodeList;
      if( !m_headersFootersMapping.TryGetValue( collection, out nodeList ) )
      {
        nodeList = new HashSet<HeadersFootersGeneratorNode>();

        m_headersFootersMapping.Add( collection, nodeList );
        CollectionChangedEventManager.AddListener( collection, this );
      }

      nodeList.Add( node );
    }
    public HeadersFootersGeneratorNode CreateHeadersFootersGeneratorNode(
      IList collection,
      GeneratorNode parent,
      GeneratorNode previous,
      GeneratorNode next )
    {
      Debug.Assert( collection != null, "collection cannot be null for CreateHeadersFootersGeneratorNode()" );

      INotifyCollectionChanged notifyCollection = collection as INotifyCollectionChanged;

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

      HeadersFootersGeneratorNode node = new HeadersFootersGeneratorNode( collection, parent );

      if( previous != null )
      {
        previous.Next = node;
      }
      node.Previous = previous;

      if( next != null )
      {
        next.Previous = node;
      }
      node.Next = next;

      node.ExpansionStateChanged += m_expansionStateChangedHandler;

      this.ConfigureHeadersFootersNotification( notifyCollection, node );

      if( parent != null )
      {
        node.AdjustItemCount( node.ItemCount );
      }

      return node;
    }
    private static void ProcessHeadersNodeVisit( HeadersFootersGeneratorNode headersNode, DataGridContext sourceContext, int minIndex, int maxIndex, IDataGridContextVisitor visitor, ref bool stopVisit )
    {
      for( int i = minIndex; i <= maxIndex; i++ )
      {
        object template = headersNode.GetAt( i );

        GroupGeneratorNode groupNode = headersNode.Parent as GroupGeneratorNode;
        if( groupNode != null )
        {
          visitor.Visit( sourceContext, ( GroupHeaderFooterItem )template, ref stopVisit );
        }
        else
        {
          visitor.Visit( sourceContext, ( DataTemplate )template, ref stopVisit );
        }

        if( stopVisit )
          break;
      }
    }
Ejemplo n.º 13
0
    private void CleanHeadersFootersNotification( HeadersFootersGeneratorNode node )
    {
      INotifyCollectionChanged notifyCollection = node.Items as INotifyCollectionChanged;
      if( notifyCollection != null )
      {
        try
        {
          List<HeadersFootersGeneratorNode> nodeList = m_headersFootersMapping[ notifyCollection ];

          nodeList.Remove( node );

          if( nodeList.Count == 0 )
          {
            notifyCollection.CollectionChanged -= OnHeadersFootersCollectionChanged;
            m_headersFootersMapping.Remove( notifyCollection );
          }
        }
        catch( Exception e )
        {
          throw new DataGridInternalException( e );
        }
      }
    }
Ejemplo n.º 14
0
    private void ConfigureHeadersFootersNotification( INotifyCollectionChanged notifyCollection, HeadersFootersGeneratorNode node )
    {
      List<HeadersFootersGeneratorNode> nodeList;
      bool keyFound = m_headersFootersMapping.TryGetValue( notifyCollection, out nodeList );

      if( keyFound == false )
      {
        nodeList = new List<HeadersFootersGeneratorNode>();

        notifyCollection.CollectionChanged += OnHeadersFootersCollectionChanged;

        m_headersFootersMapping.Add( notifyCollection, nodeList );
      }

      nodeList.Add( node );
    }