internal TableViewPageResult Generate( IEnumerable<LayoutedContainerInfo> layoutedContainers, TableViewPage lastGeneratedPage ) { m_generator = m_itemsHost.CustomItemContainerGenerator; Debug.Assert( m_generator != null ); m_generator.IsRecyclingEnabled = true; m_itemCount = m_generator.ItemCount; m_focusedContainer = DataGridItemsHost.GetItemsHostContainerFromElement( m_itemsHost, Keyboard.FocusedElement as DependencyObject ); var lastGeneratedPageSize = lastGeneratedPage.OuterPage.Length; m_oldLayoutedContainers = new Dictionary<UIElement, int>( lastGeneratedPageSize ); m_newLayoutedContainers = null; // Figure out the realized index of all currently layouted containers. foreach( var container in layoutedContainers.Select( item => item.Container ) ) { var newRealizedIndex = m_generator.GetRealizedIndexForContainer( container ); if( ( newRealizedIndex >= 0 ) || ( container == m_focusedContainer ) ) { m_oldLayoutedContainers.Add( container, newRealizedIndex ); } // The container is lost, recycle it. else { m_itemsHost.RecycleContainer( m_generator, new LayoutedContainerInfo( newRealizedIndex, container ) ); } } TableViewPageResult result; if( m_itemCount > 0 ) { m_newLayoutedContainers = new List<LayoutedContainerInfo>( lastGeneratedPageSize ); var extendedHeight = Math.Max( m_availableHeight, lastGeneratedPage.ViewportHeight ); this.PrepareRecycleCandidates( extendedHeight ); var dataGridContext = DataGridControl.GetDataGridContext( m_itemsHost ); var fillLastPage = ( dataGridContext != null ) && TableView.GetAutoFillLastPage( dataGridContext ); var pageInfo = this.GenerateContainers( m_startIndex, m_itemCount, m_availableHeight, extendedHeight, fillLastPage ); // Keep the focused container active by putting it in the layouted containers collection. if( m_focusedContainer != null ) { int newRealizedIndex; if( m_oldLayoutedContainers.TryGetValue( m_focusedContainer, out newRealizedIndex ) ) { m_oldLayoutedContainers.Remove( m_focusedContainer ); m_newLayoutedContainers.Add( new LayoutedContainerInfo( newRealizedIndex, m_focusedContainer ) ); } } result = new TableViewPageResult( pageInfo, m_newLayoutedContainers ); } else { result = new TableViewPageResult( TableViewPage.Empty, Enumerable.Empty<LayoutedContainerInfo>() ); } // Recycle the containers that have not been reused. foreach( var entry in m_oldLayoutedContainers ) { m_itemsHost.RecycleContainer( m_generator, new LayoutedContainerInfo( entry.Value, entry.Key ) ); } return result; }
private Size GetNewDesiredSize( TableViewPage pageInfo ) { double desiredHeight; double availableHeight = m_lastMeasureAvailableSize.Height; if( pageInfo == TableViewPage.Empty ) { desiredHeight = 0d; } // The current generated page displays only a subset of the data source. else if( pageInfo.InnerPage.Length < this.ScrollInfo.ExtentHeight ) { if( double.IsPositiveInfinity( availableHeight ) ) { desiredHeight = pageInfo.InnerPage.Size; } else { desiredHeight = availableHeight; } } // The current generated page displays all containers. else { var pageHeight = pageInfo.OuterPage.Size; if( double.IsPositiveInfinity( availableHeight ) ) { desiredHeight = pageHeight; } else { desiredHeight = Math.Min( availableHeight, pageHeight ); } } return new Size( m_viewportWidth, desiredHeight ); }
internal TableViewPageResult( TableViewPage pageInfo, IEnumerable<LayoutedContainerInfo> layoutedContainers ) { if( pageInfo == null ) throw new ArgumentNullException( "pageInfo" ); if( layoutedContainers == null ) throw new ArgumentNullException( "layoutedContainers" ); m_pageInfo = pageInfo; m_layoutedContainers = layoutedContainers; }