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;
    }
示例#5
0
 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;
    }