private void GenerateFocusedContainer( ICustomItemContainerGenerator generator, bool measureInvalidated, UIElement focusedElement ) { if( focusedElement == null ) return; int index = generator.GetRealizedIndexForContainer( focusedElement ); if( index >= 0 ) { if( measureInvalidated ) { this.MeasureContainer( focusedElement ); } m_layoutedContainers.Add( new LayoutedContainerInfo( index, focusedElement ) ); } else { this.RecycleContainer( focusedElement ); } }
private void GenerateContainers( ICustomItemContainerGenerator generator, int pageStartIndex, int pageEndIndex, bool measureInvalidated, ref UIElement focusedElement ) { HashSet<UIElement> unusedLayoutedContainers = new HashSet<UIElement>( m_layoutedContainers.Select( item => item.Container ) ); m_layoutedContainers.Clear(); ScrollDirection scrollDirection = this.AnimatedScrollInfo.VerticalScrollingDirection; GeneratorPosition position; GeneratorDirection direction; int currentIndex; int step; if( ( scrollDirection == ScrollDirection.Forward ) || ( scrollDirection == ScrollDirection.None ) ) { position = generator.GeneratorPositionFromIndex( pageStartIndex ); direction = GeneratorDirection.Forward; currentIndex = pageStartIndex; step = 1; } else { position = generator.GeneratorPositionFromIndex( pageEndIndex ); direction = GeneratorDirection.Backward; currentIndex = pageEndIndex; step = -1; } using( generator.StartAt( position, direction, true ) ) { while( ( currentIndex >= pageStartIndex ) && ( currentIndex <= pageEndIndex ) ) { UIElement container = this.GenerateContainer( generator, currentIndex, measureInvalidated, true ); if( container == null ) break; if( focusedElement == container ) { focusedElement = null; } // The container is now part of the page layout. Add it to the list. m_layoutedContainers.Add( new LayoutedContainerInfo( currentIndex, container ) ); m_layoutedContainersToRecycle.Remove( container ); unusedLayoutedContainers.Remove( container ); currentIndex += step; } } // A ScrollViewer may measure forever if the containers that are "underneath" the horizontal // scrollbar are the ones that required the scrollbar in the first place. if( m_lastVisiblePageIndexes != PageIndexes.Empty ) { int remainingItemCount = ( m_lastVisiblePageIndexes.EndIndex - m_lastVisiblePageIndexes.StartIndex ) - ( pageEndIndex - pageStartIndex ); if( ( remainingItemCount > 0 ) && ( this.GetMaxDesiredWidth() < this.AnimatedScrollInfo.ExtentWidth ) ) { int itemCount = generator.ItemCount; if( ( currentIndex >= 0 ) && ( currentIndex < itemCount ) ) { position = generator.GeneratorPositionFromIndex( currentIndex ); using( generator.StartAt( position, direction, true ) ) { while( ( remainingItemCount > 0 ) && ( currentIndex >= 0 ) && ( currentIndex < itemCount ) ) { UIElement container = this.GenerateContainer( generator, currentIndex, measureInvalidated, true ); if( container == null ) break; if( focusedElement == container ) { focusedElement = null; } // The container is now part of the page layout. Add it to the list. m_layoutedContainers.Add( new LayoutedContainerInfo( currentIndex, container ) ); m_layoutedContainersToRecycle.Remove( container ); unusedLayoutedContainers.Remove( container ); currentIndex += step; remainingItemCount--; } } } } } m_layoutedContainers.Sort(); // Recycle the containers that have not been reused in the current page. foreach( var container in unusedLayoutedContainers ) { // We do not recycle the focused element! if( container.IsKeyboardFocusWithin ) { Debug.Assert( focusedElement == null ); focusedElement = container; } else { int index = generator.GetRealizedIndexForContainer( container ); this.RecycleContainer( generator, index, container ); m_layoutedContainersToRecycle.Add( container ); } } }
private void RecycleUnusedStickyContainers( ICustomItemContainerGenerator generator, StickyContainerInfoList stickyContainers, StickyContainerInfoList stickyContainersToExclude, ref UIElement focusedElement ) { for( int i = stickyContainers.Count - 1; i >= 0; i-- ) { StickyContainerInfo stickyHeaderInfo = stickyContainers[ i ]; UIElement container = stickyHeaderInfo.Container; if( m_layoutedContainers.ContainsContainer( container ) ) continue; if( ( stickyContainersToExclude != null ) && ( stickyContainersToExclude.ContainsContainer( container ) ) ) continue; if( container.IsKeyboardFocusWithin ) { Debug.Assert( ( focusedElement == null ) || ( focusedElement == container ) ); focusedElement = container; continue; } int index = generator.GetRealizedIndexForContainer( container ); this.RecycleContainer( generator, index, container ); stickyContainers.RemoveAt( i ); } }
private UIElement RecycleContainers( ICustomItemContainerGenerator generator, int pageStartIndex, int pageEndIndex ) { UIElement focusedElement = null; for( int i = m_layoutedContainers.Count - 1; i >= 0; i-- ) { var container = m_layoutedContainers[ i ].Container; int index = generator.GetRealizedIndexForContainer( container ); // If the container's index is now out of view, recycle that container. if( ( index < pageStartIndex ) || ( index > pageEndIndex ) ) { // We do not recycle the focused element! if( container.IsKeyboardFocusWithin ) { focusedElement = container; } else { this.RecycleContainer( generator, index, container ); } m_layoutedContainers.RemoveAt( i ); } } return focusedElement; }
private void RecycleContainers( HashSet<UIElement> layoutedContainersToRecycle, ICustomItemContainerGenerator generator ) { foreach( UIElement containerToRecycle in layoutedContainersToRecycle ) { this.RecycleContainer( generator, generator.GetRealizedIndexForContainer( containerToRecycle ), containerToRecycle ); } }
private UIElement RecycleContainers( ICustomItemContainerGenerator generator, int pageStartIndex, int pageEndIndex ) { UIElement focusedElement = null; for( int i = 0; i < m_layoutedContainers.Count; i++ ) { LayoutedContainerInfo layoutedContainerInfo = m_layoutedContainers[ i ]; UIElement container = layoutedContainerInfo.Container; // We do not recycle the focused element! if( container.IsKeyboardFocusWithin ) { focusedElement = container; continue; } int index = generator.GetRealizedIndexForContainer( container ); // If the container's index is now out of view, recycle that container. if( ( index < pageStartIndex ) || ( index > pageEndIndex ) ) { this.RecycleContainer( generator, index, container ); m_layoutedContainersToRecycle.Add( container ); } } m_layoutedContainers.Clear(); return focusedElement; }