コード例 #1
0
    internal double GetStickyFootersRegionHeight( StickyContainerInfoList stickyFooters )
    {
      int count = stickyFooters.Count;
      double lastStickyFooterOffset = m_viewportHeight;

      for( int i = 0; i < count; i++ )
      {
        double desiredOffset = this.ComputeStickyFooterDesiredOffset( stickyFooters[ i ], lastStickyFooterOffset );
        lastStickyFooterOffset = Math.Min( desiredOffset, lastStickyFooterOffset );
      }

      return lastStickyFooterOffset;
    }
コード例 #2
0
    internal double GetStickyHeadersRegionHeight( StickyContainerInfoList stickyHeaders )
    {
      int count = stickyHeaders.Count;
      double lastStickyHeaderOffset = -m_containerHeight;

      for( int i = 0; i < count; i++ )
      {
        double desiredOffset = this.ComputeStickyHeaderDesiredOffset( stickyHeaders[ i ], lastStickyHeaderOffset );
        lastStickyHeaderOffset = Math.Max( desiredOffset, lastStickyHeaderOffset );
      }

      return lastStickyHeaderOffset + m_containerHeight;
    }
コード例 #3
0
    private void GenerateStickyHeaders( ICustomItemContainerGenerator generator, bool measureInvalidated, ref UIElement focusedElement )
    {
      CustomItemContainerGenerator customGenerator = ( CustomItemContainerGenerator )generator;

      if( !this.AreHeadersStickyCache && !this.AreGroupHeadersStickyCache && !this.AreParentRowsStickyCache )
      {
        this.RecycleUnusedStickyContainers( generator, m_stickyHeaders, null, ref focusedElement );
        m_stickyHeaders.Clear();
        return;
      }

      int numberOfContainerChecked = 0;

      StickyContainerInfoList newStickyHeaders = new StickyContainerInfoList();

      foreach( LayoutedContainerInfo layoutedContainerInfo in m_layoutedContainers )
      {
        UIElement container = layoutedContainerInfo.Container;

        // For each visible container, we must find what headers should be sticky for it.
        List<StickyContainerGenerated> stickyHeaders =
          customGenerator.GenerateStickyHeaders( container, this.AreHeadersStickyCache, this.AreGroupHeadersStickyCache, this.AreParentRowsStickyCache );

        stickyHeaders.Sort( StickyContainerGeneratedComparer.Singleton );

        // For each sticky headers returned, we must get the index of the last container
        // that could need that container to be sticky. 
        foreach( StickyContainerGenerated stickyHeaderInfo in stickyHeaders )
        {
          UIElement stickyContainer = ( UIElement )stickyHeaderInfo.StickyContainer;

          if( newStickyHeaders.ContainsContainer( stickyContainer ) )
            continue;

          int lastContainerIndex = customGenerator.GetLastHoldingContainerIndexForStickyHeader( stickyContainer );

          StickyContainerInfo stickyContainerInfo = new StickyContainerInfo( stickyContainer, stickyHeaderInfo.Index, lastContainerIndex );
          newStickyHeaders.Add( stickyContainerInfo );

          if( focusedElement == stickyContainer )
          {
            focusedElement = null;
          }

          this.HandleGeneratedStickyContainerPreparation( stickyHeaderInfo, measureInvalidated );
        }

        // We only need to find the sticky headers for one 
        // more element than what is already sticky.
        int visibleStickyHeadersCount = ( int )Math.Ceiling( this.GetStickyHeadersRegionHeight( newStickyHeaders ) / m_containerHeight );

        if( ( ++numberOfContainerChecked - visibleStickyHeadersCount ) >= 1 )
          break;
      }

      foreach( StickyContainerInfo stickyHeaderInfo in newStickyHeaders )
      {
        UIElement container = stickyHeaderInfo.Container;
        int index = m_layoutedContainers.IndexOfContainer( container );

        if( index > -1 )
        {
          m_layoutedContainers.RemoveAt( index );
        }

        m_layoutedContainersToRecycle.Remove( container );
      }

      this.RecycleUnusedStickyContainers( generator, m_stickyHeaders, newStickyHeaders, ref focusedElement );

      m_stickyHeaders.Clear();
      m_stickyHeaders.AddRange( newStickyHeaders );
      m_stickyHeaders.Sort( StickyContainerInfoComparer.Singleton );
    }
コード例 #4
0
    private void GenerateStickyFooters( ICustomItemContainerGenerator generator, bool measureInvalidated, ref UIElement focusedElement )
    {
      if( !this.AreFootersStickyCache && !this.AreGroupFootersStickyCache )
      {
        this.RecycleUnusedStickyContainers( generator, m_stickyFooters, null, ref focusedElement );
        m_stickyFooters.Clear();
        return;
      }

      CustomItemContainerGenerator customGenerator = ( CustomItemContainerGenerator )generator;

      int numberOfContainerChecked = 0;

      StickyContainerInfoList newStickyFooters = new StickyContainerInfoList();

      int layoutedContainerCount = m_layoutedContainers.Count;
      if( layoutedContainerCount > 0 )
      {
        // We must not generate sticky footers if the last container is not even at the bottom of the view!
        LayoutedContainerInfo bottomMostContainerInfo = m_layoutedContainers[ layoutedContainerCount - 1 ];
        double bottomMostContainerOffset = this.GetContainerOffsetFromIndex( bottomMostContainerInfo.RealizedIndex );

        if( ( bottomMostContainerOffset + m_containerHeight ) >= m_viewportHeight )
        {
          for( int i = layoutedContainerCount - 1; i >= 0; i-- )
          {
            LayoutedContainerInfo layoutedContainerInfo = m_layoutedContainers[ i ];
            UIElement layoutedContainer = layoutedContainerInfo.Container;

            // For each visible container, we must find what footers should be sticky for it.
            List<StickyContainerGenerated> stickyFooters =
              customGenerator.GenerateStickyFooters( layoutedContainer, this.AreFootersStickyCache, this.AreGroupFootersStickyCache );

            stickyFooters.Sort( StickyContainerGeneratedReverseComparer.Singleton );

            // For each sticky headers returned, we must get the index of the last container
            // that could need that container to be sticky. 
            foreach( StickyContainerGenerated stickyFooterInfo in stickyFooters )
            {
              UIElement stickyContainer = ( UIElement )stickyFooterInfo.StickyContainer;

              if( newStickyFooters.ContainsContainer( stickyContainer ) )
                continue;

              int firstContainerIndex = customGenerator.GetFirstHoldingContainerIndexForStickyFooter( stickyContainer );

              StickyContainerInfo stickyContainerInfo = new StickyContainerInfo( stickyContainer, stickyFooterInfo.Index, firstContainerIndex );
              newStickyFooters.Add( stickyContainerInfo );

              if( focusedElement == stickyContainer )
              {
                focusedElement = null;
              }

              this.HandleGeneratedStickyContainerPreparation( stickyFooterInfo, measureInvalidated );
            }

            // We only need to find the sticky footers for one 
            // more element than what is already sticky.
            int visibleStickyFootersCount = ( int )Math.Ceiling( ( this.AnimatedScrollInfo.ViewportHeight - this.GetStickyFootersRegionHeight( newStickyFooters ) ) / m_containerHeight );

            if( ( ++numberOfContainerChecked - visibleStickyFootersCount ) >= 1 )
              break;
          }
        }
      }

      foreach( StickyContainerInfo stickyFooterInfo in newStickyFooters )
      {
        int indexOf = m_layoutedContainers.IndexOfContainer( stickyFooterInfo.Container );

        if( indexOf > -1 )
        {
          m_layoutedContainers.RemoveAt( indexOf );
        }
      }

      this.RecycleUnusedStickyContainers( generator, m_stickyFooters, newStickyFooters, ref focusedElement );

      m_stickyFooters.Clear();
      m_stickyFooters.AddRange( newStickyFooters );
      m_stickyFooters.Sort( StickyContainerInfoReverseComparer.Singleton );
    }
コード例 #5
0
    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 );
      }
    }