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 ]; }