Exemple #1
0
        internal bool FindNodeForIndex(int index)
        {
            var success = GeneratorNodeHelper.FindNodeForIndex(ref m_state, index);

            this.EnsureState();

            return(success);
        }
    private void StartGenerator( GeneratorPosition startPos, GeneratorDirection direction )
    {
      if( this.Status == GeneratorStatus.GeneratingContainers )
      {
        throw new InvalidOperationException( "Cannot perform this operation while the generator is busy generating items" );
      }

      //set the GeneratorStatus to "Generating"
      m_generatorStatus = GeneratorStatus.GeneratingContainers;

      //Initialize the Direction
      m_generatorDirection = direction;

      //retrieve the Index for the GeneratorPosition retrieved
      m_generatorCurrentGlobalIndex = this.IndexFromGeneratorPosition( startPos );

      // case 117460: throw an exception if the GeneratorPosition is bad, but not if the itemcount is 0 
      //(and generator position maps to index 0 ).
      int itemCount = this.ItemCount;
      if( ( m_generatorCurrentGlobalIndex < 0 ) || ( ( itemCount > 0 ) && ( m_generatorCurrentGlobalIndex >= itemCount ) ) )
        throw new ArgumentOutOfRangeException( "startPos", "The specified start position is outside the range of the Generator content." );

      //case 117460: if the item count is 0, return without doing any check, GenerateNext will never process any content in that case.
      //Since the GeneratorNodeHelper is never created.
      if( itemCount == 0 )
        return;

      //and create a node helper that will assist us during the Generation process...
      m_generatorNodeHelper = new GeneratorNodeHelper( m_startNode, 0, 0 ); // start index is always 0

      //position the GeneratorNodeHelper to the appropriate node
      if( !m_generatorNodeHelper.FindNodeForIndex( m_generatorCurrentGlobalIndex ) ) //find index?!?!
      {
        //there was a problem moving the Node helper... 
        throw new DataGridInternalException();
      }

      //Calculate the offset
      m_generatorCurrentOffset = m_generatorCurrentGlobalIndex - m_generatorNodeHelper.Index;

      ItemsGeneratorNode itemsNode = m_generatorNodeHelper.CurrentNode as ItemsGeneratorNode;
      if( itemsNode != null )
      {
        m_generatorCurrentDetail = itemsNode.GetDetailNodeForIndex( m_generatorCurrentOffset, out m_generatorCurrentOffset, out m_generatorCurrentDetailIndex, out m_generatorCurrentDetailNodeIndex );
      }

      if( m_generatorCurrentDetail != null )
      {
        m_generatorCurrentDetailDisposable = ( ( IItemContainerGenerator )m_generatorCurrentDetail.DetailGenerator ).StartAt( m_generatorCurrentDetail.DetailGenerator.GeneratorPositionFromIndex( m_generatorCurrentDetailIndex ), direction, true );
      }
    }
    internal int GetStickyFooterCountForIndex(
      int index,
      bool areFootersSticky,
      bool areGroupFootersSticky )
    {
      int stickyFooterCount = 0;

      GeneratorNodeHelper nodeHelper = new GeneratorNodeHelper( m_startNode, 0, 0 );

      if( !nodeHelper.FindNodeForIndex( index ) )
      {
        // Unable to find the node, no sticky header for this node
        return 0;
      }

      GeneratorNode indexNode = nodeHelper.CurrentNode;

      ItemsGeneratorNode itemsGeneratorNode = indexNode as ItemsGeneratorNode;

      // We found an ItemsGeneratorNode
      if( itemsGeneratorNode != null )
      {
        GeneratorNode innerNode = itemsGeneratorNode.GetDetailNodeForIndex( index - nodeHelper.Index );

        DetailGeneratorNode detailNode = innerNode as DetailGeneratorNode;

        if( detailNode != null )
        {
          int detailFirstRealizedIndex = this.FindGlobalIndexForDetailNode( detailNode );
          int correctedIndex = index - detailFirstRealizedIndex;

          Debug.Assert( correctedIndex >= 0, "correctedIndex >= 0 .. 2" );
#if LOG
          Log.Assert( this, correctedIndex >= 0, "correctedIndex >= 0 .. 2" );
#endif

          stickyFooterCount +=
            detailNode.DetailGenerator.GetStickyFooterCountForIndex( correctedIndex,
                                                                     areFootersSticky,
                                                                     areGroupFootersSticky );
        }
      }

      // We want to find the HeaderFooterGeneratorNode for the container 
      // node. This is to find the footers for the container.
      nodeHelper.MoveToEnd();
      HeadersFootersGeneratorNode footersNode = nodeHelper.CurrentNode as HeadersFootersGeneratorNode;

      // There is no footers to generate if the item count of the node is 0.
      if( footersNode.ItemCount > 0 )
      {
        if( ( ( footersNode.Parent == null ) && ( areFootersSticky ) )
          || ( ( footersNode.Parent is GroupGeneratorNode ) && ( areGroupFootersSticky ) ) )
        {
          // We are generating sticky footers for a container that is already 
          // part of the footers, we need to handle it differently.
          stickyFooterCount += this.GetStickyFooterCountForNode( footersNode,
                                                                 nodeHelper.Index,
                                                                 index,
                                                                 ( footersNode != indexNode ) );
        }
      }

      // We must also find the bottom most footers for our level of detail and, if they need to be sticky,
      // we will generate the containers and add them the to list.
      HeadersFootersGeneratorNode bottomFootersNode = this.GetDetailFootersNode( nodeHelper );

      if( ( bottomFootersNode != null )
        && ( bottomFootersNode != footersNode )
        && ( bottomFootersNode.ItemCount > 0 )
        && ( areFootersSticky ) )
      {
        stickyFooterCount += this.GetStickyFooterCountForNode( bottomFootersNode, nodeHelper.Index );
      }

      return stickyFooterCount;
    }
    internal int GetStickyHeaderCountForIndex(
     int index,
     bool areHeadersSticky,
     bool areGroupHeadersSticky,
     bool areParentRowsSticky )
    {
      int stickyHeadersCount = 0;

      GeneratorNodeHelper nodeHelper = new GeneratorNodeHelper( m_startNode, 0, 0 );

      if( !nodeHelper.FindNodeForIndex( index ) )
      {
        // Unable to find the node, no sticky header for this node
        return 0;
      }

      GeneratorNode indexNode = nodeHelper.CurrentNode;

      ItemsGeneratorNode itemsGeneratorNode = indexNode as ItemsGeneratorNode;

      // We found an ItemsGeneratorNode
      if( itemsGeneratorNode != null )
      {
        GeneratorNode innerNode = itemsGeneratorNode.GetDetailNodeForIndex( index - nodeHelper.Index );

        DetailGeneratorNode detailNode = innerNode as DetailGeneratorNode;

        // Only do a special case if the index represent
        // a DetailNode
        if( detailNode != null )
        {
          if( ( areParentRowsSticky )
            && ( this.AreDetailsExpanded( detailNode.DetailContext.ParentItem ) ) )
          {
            stickyHeadersCount++;
          }

          int detailFirstRealizedIndex = this.FindGlobalIndexForDetailNode( detailNode );
          int correctedIndex = index - detailFirstRealizedIndex;

          Debug.Assert( correctedIndex >= 0, "correctedIndex >= 0 .. 1" );
#if LOG
          Log.Assert( this, correctedIndex >= 0, "correctedIndex >= 0 .. 1" );
#endif

          stickyHeadersCount +=
            detailNode.DetailGenerator.GetStickyHeaderCountForIndex( correctedIndex,
                                                                     areHeadersSticky,
                                                                     areGroupHeadersSticky,
                                                                     areParentRowsSticky );
        }
      }


      // We want to find the HeaderFooterGeneratorNode for the container 
      // node. This is to find the headers for the container.
      nodeHelper.MoveToFirst();
      HeadersFootersGeneratorNode headersNode = nodeHelper.CurrentNode as HeadersFootersGeneratorNode;

      // There is no headers to generate if the item count of the node is 0.
      if( headersNode.ItemCount > 0 )
      {
        if( ( ( headersNode.Parent == null ) && ( areHeadersSticky ) )
          || ( ( headersNode.Parent is GroupGeneratorNode ) && ( areGroupHeadersSticky ) ) )
        {
          // We are generating sticky headers for a container that is already 
          // part of the headers, we need to handle it differently.
          stickyHeadersCount += this.GetStickyHeaderCountForNode( headersNode,
                                                                  nodeHelper.Index,
                                                                  index,
                                                                  ( headersNode == indexNode ) );
        }
      }

      // We must also find the top most headers for our level of detail and, if they need to be sticky,
      // we will generate the containers and add them the to list.
      HeadersFootersGeneratorNode topMostHeaderNode = this.GetTopMostHeaderNode( nodeHelper );
      if( ( topMostHeaderNode != null )
        && ( topMostHeaderNode != headersNode )
        && ( topMostHeaderNode.ItemCount > 0 )
        && ( areHeadersSticky ) )
      {
        stickyHeadersCount += this.GetStickyHeaderCountForNode( topMostHeaderNode, nodeHelper.Index );
      }


      return stickyHeadersCount;
    }
    public DependencyObject GetRealizedContainerForIndex( int index )
    {
      //If the node tree is not created, then there can be no containers for the index.
      if( m_startNode == null )
        return null;

      GeneratorNodeHelper nodeHelper = new GeneratorNodeHelper( m_startNode, 0, 0 );

      if( !nodeHelper.FindNodeForIndex( index ) )
        throw new ArgumentException( "The specified index does not correspond to an item in the generator.", "index" );

      int indexIndex = m_genPosToIndex.IndexOf( index );

      if( indexIndex == -1 )
        return null;

      return m_genPosToContainer[ indexIndex ];
    }