/// <summary>Sets the <see cref="P:System.Windows.Controls.VirtualizingPanel.CacheLengthUnit" /> attached property.</summary>
 /// <param name="element">The object to set the property on.</param>
 /// <param name="value">The type of unit that is used by the <see cref="P:System.Windows.Controls.VirtualizingPanel.CacheLength" /> property. </param>
 // Token: 0x06005A1E RID: 23070 RVA: 0x0018D598 File Offset: 0x0018B798
 public static void SetCacheLengthUnit(DependencyObject element, VirtualizationCacheLengthUnit value)
 {
     if (element == null)
     {
         throw new ArgumentNullException("element");
     }
     element.SetValue(VirtualizingPanel.CacheLengthUnitProperty, value);
 }
Beispiel #2
0
 public static void SetCacheLengthUnit(DependencyObject element, VirtualizationCacheLengthUnit unit)
 {
     NoesisGUI_PINVOKE.VirtualizingPanel_SetCacheLengthUnit(DependencyObject.getCPtr(element), (int)unit);
     if (NoesisGUI_PINVOKE.SWIGPendingException.Pending)
     {
         throw NoesisGUI_PINVOKE.SWIGPendingException.Retrieve();
     }
 }
 public HierarchicalVirtualizationConstraints(VirtualizationCacheLength cacheLength,
     VirtualizationCacheLengthUnit cacheLengthUnit,
     Rect viewport)
 {
     _cacheLength = cacheLength;
     _cacheLengthUnit = cacheLengthUnit;
     _viewport = viewport;
 }
Beispiel #4
0
 public HierarchicalVirtualizationConstraints(VirtualizationCacheLength cacheLength,
                                              VirtualizationCacheLengthUnit cacheLengthUnit,
                                              Rect viewport)
 {
     _cacheLength     = cacheLength;
     _cacheLengthUnit = cacheLengthUnit;
     _viewport        = viewport;
 }
Beispiel #5
0
 public HierarchicalVirtualizationConstraints(VirtualizationCacheLength cacheLength,
                                              VirtualizationCacheLengthUnit cacheLengthUnit,
                                              Rect viewport)
 {
     _cacheLength      = cacheLength;
     _cacheLengthUnit  = cacheLengthUnit;
     _viewport         = viewport;
     _scrollGeneration = 0;  // internal field set separately by caller
 }
Beispiel #6
0
        public static VirtualizationCacheLengthUnit GetCacheLengthUnit(DependencyObject element)
        {
            VirtualizationCacheLengthUnit ret = (VirtualizationCacheLengthUnit)NoesisGUI_PINVOKE.VirtualizingPanel_GetCacheLengthUnit(DependencyObject.getCPtr(element));

            if (NoesisGUI_PINVOKE.SWIGPendingException.Pending)
            {
                throw NoesisGUI_PINVOKE.SWIGPendingException.Retrieve();
            }
            return(ret);
        }
Beispiel #7
0
 public static void SetCacheLengthUnit(DependencyObject element, VirtualizationCacheLengthUnit unit)
 {
     if (element == null)
     {
         throw new ArgumentNullException("element");
     }
     {
         NoesisGUI_PINVOKE.VirtualizingPanel_SetCacheLengthUnit(DependencyObject.getCPtr(element), (int)unit);
     }
 }
Beispiel #8
0
 public static VirtualizationCacheLengthUnit GetCacheLengthUnit(DependencyObject element)
 {
     if (element == null)
     {
         throw new ArgumentNullException("element");
     }
     {
         VirtualizationCacheLengthUnit ret = (VirtualizationCacheLengthUnit)NoesisGUI_PINVOKE.VirtualizingPanel_GetCacheLengthUnit(DependencyObject.getCPtr(element));
         return(ret);
     }
 }
Beispiel #9
0
        public static VirtualizationCacheLengthUnit Unbox_VirtualizationCacheLengthUnit(IntPtr val)
        {
            VirtualizationCacheLengthUnit ret = (VirtualizationCacheLengthUnit)NoesisGUI_PINVOKE.Unbox_VirtualizationCacheLengthUnit(val);

            return(ret);
        }
Beispiel #10
0
        private void MeasureChild(
            ref IItemContainerGenerator generator,
            ref IContainItemStorage itemStorageProvider,
            ref object parentItem,
            ref bool hasUniformOrAverageContainerSizeBeenSet,
            ref double computedUniformOrAverageContainerSize,
            ref bool computedAreContainersUniformlySized,
            ref IList items,
            ref object item,
            ref IList children,
            ref int childIndex,
            ref bool visualOrderChanged,
            ref bool isHorizontal,
            ref Size childConstraint,
            ref Rect viewport,
            ref VirtualizationCacheLength cacheSize,
            ref VirtualizationCacheLengthUnit cacheUnit,
            ref bool foundFirstItemInViewport,
            ref double firstItemInViewportOffset,
            ref Size stackPixelSize,
            ref Size stackPixelSizeInViewport,
            ref Size stackPixelSizeInCacheBeforeViewport,
            ref Size stackPixelSizeInCacheAfterViewport,
            ref Size stackLogicalSize,
            ref Size stackLogicalSizeInViewport,
            ref Size stackLogicalSizeInCacheBeforeViewport,
            ref Size stackLogicalSizeInCacheAfterViewport,
            ref bool mustDisableVirtualization,
            bool isBeforeFirstItem,
            bool isAfterFirstItem,
            bool isAfterLastItem,
            bool skipActualMeasure,
            bool skipGeneration,
            ref bool hasBringIntoViewContainerBeenMeasured,
            ref bool hasVirtualizingChildren)
        {
            UIElement child = null;
            IHierarchicalVirtualizationAndScrollInfo virtualizingChild = null;
            Rect childViewport = Rect.Empty;
            VirtualizationCacheLength childCacheSize = new VirtualizationCacheLength(0.0);
            VirtualizationCacheLengthUnit childCacheUnit = VirtualizationCacheLengthUnit.Pixel;
            Size childDesiredSize = new Size();

            //
            // Get and connect the next child.
            //
            if (!skipActualMeasure && !skipGeneration)
            {
                bool newlyRealized;
                child = generator.GenerateNext(out newlyRealized) as UIElement;

                ItemContainerGenerator icg;
                if (child == null && (icg = generator as ItemContainerGenerator) != null)
                {
                    icg.Verify();
                }

                visualOrderChanged |= AddContainerFromGenerator(childIndex, child, newlyRealized, isBeforeFirstItem);
            }
            else
            {
                child = (UIElement)children[childIndex];
            }

            hasBringIntoViewContainerBeenMeasured |= (child == _bringIntoViewContainer);

            //
            // Set viewport constraints
            //

            bool isChildHorizontal = isHorizontal;
            virtualizingChild = GetVirtualizingChild(child, ref isChildHorizontal);

            SetViewportForChild(
                isHorizontal,
                itemStorageProvider,
                computedAreContainersUniformlySized,
                computedUniformOrAverageContainerSize,
                mustDisableVirtualization,
                child,
                virtualizingChild,
                item,
                isBeforeFirstItem,
                isAfterFirstItem,
                firstItemInViewportOffset,
                viewport,
                cacheSize,
                cacheUnit,
                stackPixelSize,
                stackPixelSizeInViewport,
                stackPixelSizeInCacheBeforeViewport,
                stackPixelSizeInCacheAfterViewport,
                stackLogicalSize,
                stackLogicalSizeInViewport,
                stackLogicalSizeInCacheBeforeViewport,
                stackLogicalSizeInCacheAfterViewport,
                out childViewport,
                ref childCacheSize,
                ref childCacheUnit);

            //
            // Measure the child
            //

            if (!skipActualMeasure)
            {
                child.Measure(childConstraint);
            }

            childDesiredSize = child.DesiredSize;

            //
            // Accumulate child size.
            //

            if (virtualizingChild != null)
            {
                //
                // Update the virtualizingChild once more to really be sure
                // that we can trust the Desired values from it. Previously
                // we may have bypassed some checks because the ItemsHost
                // wasn't connected.
                //
                virtualizingChild = GetVirtualizingChild(child, ref isChildHorizontal);

                mustDisableVirtualization |=
                    (virtualizingChild != null && virtualizingChild.MustDisableVirtualization) ||
                    isChildHorizontal != isHorizontal;
            }

            Size childPixelSize, childPixelSizeInViewport, childPixelSizeInCacheBeforeViewport, childPixelSizeInCacheAfterViewport;
            Size childLogicalSize, childLogicalSizeInViewport, childLogicalSizeInCacheBeforeViewport, childLogicalSizeInCacheAfterViewport;

            GetSizesForChild(
                isHorizontal,
                isChildHorizontal,
                isBeforeFirstItem,
                isAfterLastItem,
                virtualizingChild,
                childDesiredSize,
                childViewport,
                childCacheSize,
                childCacheUnit,
                out childPixelSize,
                out childPixelSizeInViewport,
                out childPixelSizeInCacheBeforeViewport,
                out childPixelSizeInCacheAfterViewport,
                out childLogicalSize,
                out childLogicalSizeInViewport,
                out childLogicalSizeInCacheBeforeViewport,
                out childLogicalSizeInCacheAfterViewport);

            UpdateStackSizes(
                isHorizontal,
                foundFirstItemInViewport,
                childPixelSize,
                childPixelSizeInViewport,
                childPixelSizeInCacheBeforeViewport,
                childPixelSizeInCacheAfterViewport,
                childLogicalSize,
                childLogicalSizeInViewport,
                childLogicalSizeInCacheBeforeViewport,
                childLogicalSizeInCacheAfterViewport,
                ref stackPixelSize,
                ref stackPixelSizeInViewport,
                ref stackPixelSizeInCacheBeforeViewport,
                ref stackPixelSizeInCacheAfterViewport,
                ref stackLogicalSize,
                ref stackLogicalSizeInViewport,
                ref stackLogicalSizeInCacheBeforeViewport,
                ref stackLogicalSizeInCacheAfterViewport);

            //
            // Cache the container size.
            //

            if (VirtualizingPanel.GetShouldCacheContainerSize(child))
            {
                SetContainerSizeForItem(
                    itemStorageProvider,
                    parentItem,
                    item,
                    IsPixelBased ? childPixelSize : childLogicalSize,
                    isHorizontal,
                    ref hasUniformOrAverageContainerSizeBeenSet,
                    ref computedUniformOrAverageContainerSize,
                    ref computedAreContainersUniformlySized);
            }

            if (virtualizingChild != null)
            {
                hasVirtualizingChildren = true;
            }
        }
Beispiel #11
0
        /// <summary>
        /// Returns the size of the child in pixel and logical units and also identifies the part of the child visible in the viewport.
        /// </summary>
        private void GetSizesForChild(
            bool isHorizontal,
            bool isChildHorizontal,
            bool isBeforeFirstItem,
            bool isAfterLastItem,
            IHierarchicalVirtualizationAndScrollInfo virtualizingChild,
            Size childDesiredSize,
            Rect childViewport,
            VirtualizationCacheLength childCacheSize,
            VirtualizationCacheLengthUnit childCacheUnit,
            out Size childPixelSize,
            out Size childPixelSizeInViewport,
            out Size childPixelSizeInCacheBeforeViewport,
            out Size childPixelSizeInCacheAfterViewport,
            out Size childLogicalSize,
            out Size childLogicalSizeInViewport,
            out Size childLogicalSizeInCacheBeforeViewport,
            out Size childLogicalSizeInCacheAfterViewport)
        {
            childPixelSize = new Size();
            childPixelSizeInViewport = new Size();
            childPixelSizeInCacheBeforeViewport = new Size();
            childPixelSizeInCacheAfterViewport = new Size();

            childLogicalSize = new Size();
            childLogicalSizeInViewport = new Size();
            childLogicalSizeInCacheBeforeViewport = new Size();
            childLogicalSizeInCacheAfterViewport = new Size();

            if (virtualizingChild != null)
            {
                RelativeHeaderPosition headerPosition = RelativeHeaderPosition.Top; // virtualizingChild.RelativeHeaderPosition;
                HierarchicalVirtualizationHeaderDesiredSizes headerDesiredSizes = virtualizingChild.HeaderDesiredSizes;
                HierarchicalVirtualizationItemDesiredSizes itemDesiredSizes = virtualizingChild.ItemDesiredSizes;

                Size pixelHeaderSize = headerDesiredSizes.PixelSize;
                Size logicalHeaderSize = headerDesiredSizes.LogicalSize;

                childPixelSize = childDesiredSize;

                if (headerPosition == RelativeHeaderPosition.Top || headerPosition == RelativeHeaderPosition.Bottom)
                {
                    childLogicalSize.Height = itemDesiredSizes.LogicalSize.Height + logicalHeaderSize.Height;
                    childLogicalSize.Width = Math.Max(itemDesiredSizes.LogicalSize.Width, logicalHeaderSize.Width);
                }
                else // if (headerPosition == RelativeHeaderPosition.Left || headerPosition == RelativeHeaderPosition.Right)
                {
                    childLogicalSize.Width = itemDesiredSizes.LogicalSize.Width + logicalHeaderSize.Width;
                    childLogicalSize.Height = Math.Max(itemDesiredSizes.LogicalSize.Height, logicalHeaderSize.Height);
                }

                if (IsPixelBased &&
                    ((isHorizontal && DoubleUtil.AreClose(itemDesiredSizes.PixelSize.Width, itemDesiredSizes.PixelSizeInViewport.Width)) ||
                    (!isHorizontal && DoubleUtil.AreClose(itemDesiredSizes.PixelSize.Height, itemDesiredSizes.PixelSizeInViewport.Height))))
                {
                    Rect childItemsViewport = childViewport;

                    if (headerPosition == RelativeHeaderPosition.Top || headerPosition == RelativeHeaderPosition.Left)
                    {
                        VirtualizationCacheLength childItemsCacheSize = childCacheSize;
                        VirtualizationCacheLengthUnit childItemsCacheUnit = childCacheUnit;

                        AdjustNonScrollingViewportForHeader(virtualizingChild, ref childItemsViewport, ref childItemsCacheSize, ref childItemsCacheUnit);
                    }

                    GetSizesForChildIntersectingTheViewport(
                        isHorizontal,
                        isChildHorizontal,
                        itemDesiredSizes.PixelSizeInViewport,
                        itemDesiredSizes.LogicalSizeInViewport,
                        childItemsViewport,
                        ref childPixelSizeInViewport,
                        ref childLogicalSizeInViewport,
                        ref childPixelSizeInCacheBeforeViewport,
                        ref childLogicalSizeInCacheBeforeViewport,
                        ref childPixelSizeInCacheAfterViewport,
                        ref childLogicalSizeInCacheAfterViewport);
                }
                else
                {
                    StackSizes(isHorizontal, ref childPixelSizeInViewport, itemDesiredSizes.PixelSizeInViewport);
                    StackSizes(isHorizontal, ref childLogicalSizeInViewport, itemDesiredSizes.LogicalSizeInViewport);
                }

                if (isChildHorizontal == isHorizontal)
                {
                    StackSizes(isHorizontal, ref childPixelSizeInCacheBeforeViewport, itemDesiredSizes.PixelSizeBeforeViewport);
                    StackSizes(isHorizontal, ref childLogicalSizeInCacheBeforeViewport, itemDesiredSizes.LogicalSizeBeforeViewport);
                    StackSizes(isHorizontal, ref childPixelSizeInCacheAfterViewport, itemDesiredSizes.PixelSizeAfterViewport);
                    StackSizes(isHorizontal, ref childLogicalSizeInCacheAfterViewport, itemDesiredSizes.LogicalSizeAfterViewport);
                }

                Rect childHeaderViewport = childViewport;
                Size childHeaderPixelSizeInViewport = new Size();
                Size childHeaderLogicalSizeInViewport = new Size();
                Size childHeaderPixelSizeInCacheBeforeViewport = new Size();
                Size childHeaderLogicalSizeInCacheBeforeViewport = new Size();
                Size childHeaderPixelSizeInCacheAfterViewport = new Size();
                Size childHeaderLogicalSizeInCacheAfterViewport = new Size();
                bool isChildHeaderHorizontal = (headerPosition == RelativeHeaderPosition.Left || headerPosition == RelativeHeaderPosition.Right);

                if (headerPosition == RelativeHeaderPosition.Bottom || headerPosition == RelativeHeaderPosition.Right)
                {
                    VirtualizationCacheLength childHeaderCacheSize = childCacheSize;
                    VirtualizationCacheLengthUnit childHeaderCacheUnit = childCacheUnit;

                    AdjustNonScrollingViewportForItems(virtualizingChild, ref childHeaderViewport, ref childHeaderCacheSize, ref childHeaderCacheUnit);
                }

                if (isBeforeFirstItem)
                {
                    childHeaderPixelSizeInCacheBeforeViewport = pixelHeaderSize;
                    childHeaderLogicalSizeInCacheBeforeViewport = logicalHeaderSize;
                }
                else if (isAfterLastItem)
                {
                    childHeaderPixelSizeInCacheAfterViewport = pixelHeaderSize;
                    childHeaderLogicalSizeInCacheAfterViewport = logicalHeaderSize;
                }
                else
                {
                    GetSizesForChildIntersectingTheViewport(
                        isHorizontal,
                        isChildHorizontal,
                        pixelHeaderSize,
                        logicalHeaderSize,
                        childHeaderViewport,
                        ref childHeaderPixelSizeInViewport,
                        ref childHeaderLogicalSizeInViewport,
                        ref childHeaderPixelSizeInCacheBeforeViewport,
                        ref childHeaderLogicalSizeInCacheBeforeViewport,
                        ref childHeaderPixelSizeInCacheAfterViewport,
                        ref childHeaderLogicalSizeInCacheAfterViewport);
                }

                StackSizes(isChildHeaderHorizontal, ref childPixelSizeInViewport, childHeaderPixelSizeInViewport);
                StackSizes(isChildHeaderHorizontal, ref childLogicalSizeInViewport, childHeaderLogicalSizeInViewport);
                StackSizes(isChildHeaderHorizontal, ref childPixelSizeInCacheBeforeViewport, childHeaderPixelSizeInCacheBeforeViewport);
                StackSizes(isChildHeaderHorizontal, ref childLogicalSizeInCacheBeforeViewport, childHeaderLogicalSizeInCacheBeforeViewport);
                StackSizes(isChildHeaderHorizontal, ref childPixelSizeInCacheAfterViewport, childHeaderPixelSizeInCacheAfterViewport);
                StackSizes(isChildHeaderHorizontal, ref childLogicalSizeInCacheAfterViewport, childHeaderLogicalSizeInCacheAfterViewport);
            }
            else
            {
                childPixelSize = childDesiredSize;
                childLogicalSize = new Size(DoubleUtil.GreaterThan(childPixelSize.Width, 0) ? 1 : 0,
                                            DoubleUtil.GreaterThan(childPixelSize.Height, 0) ? 1 : 0);

                if (isBeforeFirstItem)
                {
                    childPixelSizeInCacheBeforeViewport = childDesiredSize;
                    childLogicalSizeInCacheBeforeViewport = new Size(DoubleUtil.GreaterThan(childPixelSizeInCacheBeforeViewport.Width, 0) ? 1 : 0,
                                                                     DoubleUtil.GreaterThan(childPixelSizeInCacheBeforeViewport.Height, 0) ? 1 : 0);
                }
                else if (isAfterLastItem)
                {
                    childPixelSizeInCacheAfterViewport = childDesiredSize;
                    childLogicalSizeInCacheAfterViewport = new Size(DoubleUtil.GreaterThan(childPixelSizeInCacheAfterViewport.Width, 0) ? 1 : 0,
                                                                    DoubleUtil.GreaterThan(childPixelSizeInCacheAfterViewport.Height, 0) ? 1 : 0);
                }
                else
                {
                    GetSizesForChildIntersectingTheViewport(
                        isHorizontal,
                        isHorizontal,
                        childPixelSize,
                        childLogicalSize,
                        childViewport,
                        ref childPixelSizeInViewport,
                        ref childLogicalSizeInViewport,
                        ref childPixelSizeInCacheBeforeViewport,
                        ref childLogicalSizeInCacheBeforeViewport,
                        ref childPixelSizeInCacheAfterViewport,
                        ref childLogicalSizeInCacheAfterViewport);
                }
            }
        }
Beispiel #12
0
        /// <summary>
        /// Called when to set a new viewport on the child when it is about to be measured.
        /// </summary>
        private void SetViewportForChild(
            bool isHorizontal,
            IContainItemStorage itemStorageProvider,
            bool areContainersUniformlySized,
            double uniformOrAverageContainerSize,
            bool mustDisableVirtualization,
            UIElement child,
            IHierarchicalVirtualizationAndScrollInfo virtualizingChild,
            object item,
            bool isBeforeFirstItem,
            bool isAfterFirstItem,
            double firstItemInViewportOffset,
            Rect parentViewport,
            VirtualizationCacheLength parentCacheSize,
            VirtualizationCacheLengthUnit parentCacheUnit,
            Size stackPixelSize,
            Size stackPixelSizeInViewport,
            Size stackPixelSizeInCacheBeforeViewport,
            Size stackPixelSizeInCacheAfterViewport,
            Size stackLogicalSize,
            Size stackLogicalSizeInViewport,
            Size stackLogicalSizeInCacheBeforeViewport,
            Size stackLogicalSizeInCacheAfterViewport,
            out Rect childViewport,
            ref VirtualizationCacheLength childCacheSize,
            ref VirtualizationCacheLengthUnit childCacheUnit)
        {
            childViewport = parentViewport;

            //
            // Adjust viewport offset for the child by deducting
            // the dimensions of the previous siblings.
            //
            if (isHorizontal)
            {
                if (isBeforeFirstItem)
                {
                    Size containerSize;
                    GetContainerSizeForItem(itemStorageProvider, item, isHorizontal, areContainersUniformlySized, uniformOrAverageContainerSize, out containerSize);
                    childViewport.X = (IsPixelBased ? stackPixelSizeInCacheBeforeViewport.Width : stackLogicalSizeInCacheBeforeViewport.Width) + containerSize.Width;
                    childViewport.Width = 0.0;
                }
                else if (isAfterFirstItem)
                {
                    childViewport.X = Math.Min(childViewport.X, 0) -
                                      (IsPixelBased ? stackPixelSizeInViewport.Width + stackPixelSizeInCacheAfterViewport.Width :
                                                       stackLogicalSizeInViewport.Width + stackLogicalSizeInCacheAfterViewport.Width);

                    childViewport.Width = Math.Max(childViewport.Width - stackPixelSizeInViewport.Width, 0.0);
                }
                else
                {
                    childViewport.X -= firstItemInViewportOffset;
                    childViewport.Width = Math.Max(childViewport.Width - stackPixelSizeInViewport.Width, 0.0);
                }

                if (parentCacheUnit == VirtualizationCacheLengthUnit.Item)
                {
                    childCacheSize = new VirtualizationCacheLength(
                        isAfterFirstItem || DoubleUtil.LessThanOrClose(childViewport.X, 0.0) ?
                            0.0 :
                            Math.Max(parentCacheSize.CacheBeforeViewport - stackLogicalSizeInCacheBeforeViewport.Width, 0.0),
                        isBeforeFirstItem ?
                            0.0 :
                            Math.Max(parentCacheSize.CacheAfterViewport - stackLogicalSizeInCacheAfterViewport.Width, 0.0));
                    childCacheUnit = VirtualizationCacheLengthUnit.Item;
                }
                else if (parentCacheUnit == VirtualizationCacheLengthUnit.Pixel)
                {
                    childCacheSize = new VirtualizationCacheLength(
                        isAfterFirstItem || DoubleUtil.LessThanOrClose(childViewport.X, 0.0) ?
                            0.0 :
                            Math.Max(parentCacheSize.CacheBeforeViewport - stackPixelSizeInCacheBeforeViewport.Width, 0.0),
                        isBeforeFirstItem ?
                            0.0 :
                            Math.Max(parentCacheSize.CacheAfterViewport - stackPixelSizeInCacheAfterViewport.Width, 0.0));
                    childCacheUnit = VirtualizationCacheLengthUnit.Pixel;
                }
            }
            else
            {
                if (isBeforeFirstItem)
                {
                    Size containerSize;
                    GetContainerSizeForItem(itemStorageProvider, item, isHorizontal, areContainersUniformlySized, uniformOrAverageContainerSize, out containerSize);
                    childViewport.Y = (IsPixelBased ? stackPixelSizeInCacheBeforeViewport.Height : stackLogicalSizeInCacheBeforeViewport.Height) + containerSize.Height;
                    childViewport.Height = 0.0;
                }
                else if (isAfterFirstItem)
                {
                    childViewport.Y = Math.Min(childViewport.Y, 0) -
                                      (IsPixelBased ? stackPixelSizeInViewport.Height + stackPixelSizeInCacheAfterViewport.Height :
                                                       stackLogicalSizeInViewport.Height + stackLogicalSizeInCacheAfterViewport.Height);

                    childViewport.Height = Math.Max(childViewport.Height - stackPixelSizeInViewport.Height, 0.0);
                }
                else
                {
                    childViewport.Y -= firstItemInViewportOffset;
                    childViewport.Height = Math.Max(childViewport.Height - stackPixelSizeInViewport.Height, 0.0);
                }

                if (parentCacheUnit == VirtualizationCacheLengthUnit.Item)
                {
                    childCacheSize = new VirtualizationCacheLength(
                        isAfterFirstItem || DoubleUtil.LessThanOrClose(childViewport.Y, 0.0) ?
                            0.0 :
                            Math.Max(parentCacheSize.CacheBeforeViewport - stackLogicalSizeInCacheBeforeViewport.Height, 0.0),
                        isBeforeFirstItem ?
                            0.0 :
                            Math.Max(parentCacheSize.CacheAfterViewport - stackLogicalSizeInCacheAfterViewport.Height, 0.0));
                    childCacheUnit = VirtualizationCacheLengthUnit.Item;
                }
                else if (parentCacheUnit == VirtualizationCacheLengthUnit.Pixel)
                {
                    childCacheSize = new VirtualizationCacheLength(
                        isAfterFirstItem || DoubleUtil.LessThanOrClose(childViewport.Y, 0.0) ?
                            0.0 :
                            Math.Max(parentCacheSize.CacheBeforeViewport - stackPixelSizeInCacheBeforeViewport.Height, 0.0),
                        isBeforeFirstItem ?
                            0.0 :
                            Math.Max(parentCacheSize.CacheAfterViewport - stackPixelSizeInCacheAfterViewport.Height, 0.0));
                    childCacheUnit = VirtualizationCacheLengthUnit.Pixel;
                }
            }

            if (virtualizingChild != null)
            {
                virtualizingChild.Constraints = new HierarchicalVirtualizationConstraints(
                    childCacheSize,
                    childCacheUnit,
                    childViewport);
                virtualizingChild.InBackgroundLayout = MeasureCaches;
                virtualizingChild.MustDisableVirtualization = mustDisableVirtualization;
            }

            if (child is IHierarchicalVirtualizationAndScrollInfo)
            {
                //
                // Ensure that measure is invalid through the items panel
                // of the child, so it can react to the new viewport.
                //
                InvalidateMeasureOnItemsHost((IHierarchicalVirtualizationAndScrollInfo)child);
            }
        }
Beispiel #13
0
        /// <summary>
        /// Initializes the viewport for this panel.
        /// </summary>
        private void InitializeViewport(
            object parentItem,
            IContainItemStorage parentItemStorageProvider,
            IHierarchicalVirtualizationAndScrollInfo virtualizationInfoProvider,
            bool isHorizontal,
            Size constraint,
            ref Rect viewport,
            ref VirtualizationCacheLength cacheSize,
            ref VirtualizationCacheLengthUnit cacheUnit,
            out Rect extendedViewport)
        {

            Size extent = new Size();
            bool isVSP45Compat = IsVSP45Compat;

            if (IsScrolling)
            {
                //
                // We're the top level scrolling panel. Fetch the offset from the _scrollData.
                //

                Size size;
                double offsetX, offsetY;
                Size viewportSize;

                size = constraint;
                offsetX = _scrollData._offset.X;
                offsetY = _scrollData._offset.Y;
                extent = _scrollData._extent;
                viewportSize = _scrollData._viewport;

                if (!IsScrollActive || IgnoreMaxDesiredSize)
                {
                    _scrollData._maxDesiredSize = new Size();
                }

                if (IsPixelBased)
                {
                    viewport = new Rect(offsetX, offsetY, size.Width, size.Height);
                    CoerceScrollingViewportOffset(ref viewport, extent, isHorizontal);
                }
                else
                {
                    viewport = new Rect(offsetX, offsetY, viewportSize.Width, viewportSize.Height);
                    CoerceScrollingViewportOffset(ref viewport, extent, isHorizontal);
                    viewport.Size = size;
                }

                if (IsVirtualizing)
                {
                    cacheSize = VirtualizingStackPanel.GetCacheLength(this);
                    cacheUnit = VirtualizingStackPanel.GetCacheLengthUnit(this);

                    if (DoubleUtil.GreaterThan(cacheSize.CacheBeforeViewport, 0) ||
                        DoubleUtil.GreaterThan(cacheSize.CacheAfterViewport, 0))
                    {
                        if (!MeasureCaches)
                        {
                            WasLastMeasurePassAnchored = (_firstContainerInViewport != null) || (_bringIntoViewLeafContainer != null);

                            DispatcherOperation measureCachesOperation = MeasureCachesOperationField.GetValue(this);
                            if (measureCachesOperation == null)
                            {
                                Action measureCachesAction = null;
                                int retryCount = 3;
                                measureCachesAction = (Action)delegate()
                                    {
                                        Debug.Assert(retryCount >=0, "retry MeasureCaches too often");
                                        bool isLayoutDirty = (0 < retryCount--) && (MeasureDirty || ArrangeDirty);
                                        try
                                        {
                                            if (isVSP45Compat || !isLayoutDirty)
                                            {
                                                MeasureCachesOperationField.ClearValue(this);

                                                MeasureCaches = true;

                                                if (WasLastMeasurePassAnchored)
                                                {
                                                    SetAnchorInformation(isHorizontal);
                                                }

                                                InvalidateMeasure();
                                                UpdateLayout();
                                            }
                                        }
                                        finally
                                        {
                                            // check whether UpdateLayout finished the job
                                            isLayoutDirty = isLayoutDirty ||
                                                    ((0 < retryCount) && (MeasureDirty || ArrangeDirty));
                                            if (!isVSP45Compat && isLayoutDirty)
                                            {
                                                // try the measure-cache pass again later.
                                                // Note that we only do this when:
                                                // 1. this VSP's layout is dirty, either because
                                                //    a. it was dirty to begin with so we
                                                //       skipped UpdateLayout, or
                                                //    b. UpdateLayout ran, but left this VSP's
                                                //       layout dirty.
                                                // 2. we haven't run out of retries
                                                // 3. we're not in 4.5-compat mode
                                                //
                                                // (1) can happen if layout times out and moves to
                                                //     background.
                                                // (2) protects against loops when an app calls
                                                //     VSP.Measure directly, outside of the normal
                                                //     layout system (real appps don't do this,
                                                //     but test code does - it happens in the DrtXaml test).
                                                // (3) preserves compat with 4.5RTM, where the
                                                //     "move to background" situation led to an
                                                //     infinite loop.
                                                MeasureCachesOperationField.SetValue(this,
                                                    Dispatcher.BeginInvoke(DispatcherPriority.Background, measureCachesAction));
                                            }

                                            MeasureCaches = false;

                                            // If there is a pending anchor operation that got registered in
                                            // the current pass, or if layout didn't finish, we don't want to
                                            // clear the IsScrollActive flag.
                                            // We should allow that measure pass to also settle and then clear
                                            // the flag.

                                            DispatcherOperation anchoredInvalidateMeasureOperation = AnchoredInvalidateMeasureOperationField.GetValue(this);
                                            if (anchoredInvalidateMeasureOperation == null && (isVSP45Compat || !isLayoutDirty))
                                            {
                                                if (isVSP45Compat)
                                                {
                                                    IsScrollActive = false;
                                                }
                                                else if (IsScrollActive)
                                                {
                                                    // keep IsScrollActive set until the
                                                    // anchored measure has occurred.  It may
                                                    // need to remeasure, which should count
                                                    // as part of the scroll operation
                                                    DispatcherOperation clearIsScrollActiveOperation = ClearIsScrollActiveOperationField.GetValue(this);
                                                    if (clearIsScrollActiveOperation != null)
                                                    {
                                                        clearIsScrollActiveOperation.Abort();
                                                    }
                                                    clearIsScrollActiveOperation = Dispatcher.BeginInvoke(DispatcherPriority.Background,
                                                        (Action)ClearIsScrollActive);

                                                    ClearIsScrollActiveOperationField.SetValue(this, clearIsScrollActiveOperation);
                                                }
                                            }
                                        }
                                    };
                                measureCachesOperation = Dispatcher.BeginInvoke(DispatcherPriority.Background,
                                                                                measureCachesAction);
                                MeasureCachesOperationField.SetValue(this, measureCachesOperation);
                            }
                        }
                    }
                    else if (IsScrollActive)
                    {
                        DispatcherOperation clearIsScrollActiveOperation = ClearIsScrollActiveOperationField.GetValue(this);
                        if (clearIsScrollActiveOperation == null)
                        {
                            clearIsScrollActiveOperation = Dispatcher.BeginInvoke(DispatcherPriority.Background,
                                (Action)ClearIsScrollActive);

                            ClearIsScrollActiveOperationField.SetValue(this, clearIsScrollActiveOperation);
                        }
                    }

                    NormalizeCacheLength(isHorizontal, viewport, ref cacheSize, ref cacheUnit);
                }
                else
                {
                    cacheSize = new VirtualizationCacheLength(
                        Double.PositiveInfinity,
                        IsViewportEmpty(isHorizontal, viewport) ?
                        0.0 :
                        Double.PositiveInfinity);
                    cacheUnit = VirtualizationCacheLengthUnit.Pixel;

                    ClearAsyncOperations();
                }
            }
            else if (virtualizationInfoProvider != null)
            {
                //
                // Adjust the viewport offset for a non scrolling panel to account for the HeaderSize
                // when virtualizing.
                //
                HierarchicalVirtualizationConstraints virtualizationConstraints = virtualizationInfoProvider.Constraints;
                viewport = virtualizationConstraints.Viewport;
                cacheSize = virtualizationConstraints.CacheLength;
                cacheUnit = virtualizationConstraints.CacheLengthUnit;
                MeasureCaches = virtualizationInfoProvider.InBackgroundLayout;

                if (isVSP45Compat)
                {
                    AdjustNonScrollingViewportForHeader(virtualizationInfoProvider, ref viewport, ref cacheSize, ref cacheUnit);
                }
                else
                {
                    AdjustNonScrollingViewportForInset(isHorizontal, parentItem, parentItemStorageProvider, virtualizationInfoProvider, ref viewport, ref cacheSize, ref cacheUnit);

                    // The viewport position may be expressed in an old coordinate system
                    // relying on an old average container size.  Using that position would
                    // produce bad results;  for example the first step in Measure computes
                    // the first item that intersects the viewport - it uses the latest
                    // average container size, and hence would choose the wrong item
                    // (from user's point of view, the panel scrolls to a random place).
                    //      To work around this, ComputeEffectiveOffset stores a list
                    // of substitute offsets when the ave container size changes;
                    // this instructs this method to replace an old offset with a new
                    // one (appearing last) that's the equivalent in the current coordinate
                    // system.
                    //      This replacement stays in effect until the parent panel gives us
                    // an offset from a more recent coordinate change, after which older
                    // offsets won't appear again.   Or an offset that's not on the
                    // list at all, which means a new scroll motion has started.
                    DependencyObject container = virtualizationInfoProvider as DependencyObject;
                    List<Double> offsetList = EffectiveOffsetInformationField.GetValue(container);
                    if (offsetList != null)
                    {
                        if (ScrollTracer.IsEnabled && ScrollTracer.IsTracing(this))
                        {
                            object[] args = new object[offsetList.Count + 1];
                            args[0] = viewport.Location;
                            for (int i=0; i<offsetList.Count; ++i)
                            {
                                args[i+1] = offsetList[i];
                            }
                            ScrollTracer.Trace(this, ScrollTraceOp.UseSubstOffset,
                                args);
                        }

                        // find the given offset on the list
                        double offset = isHorizontal ? viewport.X : viewport.Y;
                        int index = offsetList.IndexOf(offset);

                        // if it appears, susbstitue the last offset
                        if (index >= 0)
                        {
                            if (isHorizontal)
                            {
                                viewport.X = offsetList[offsetList.Count-1];
                            }
                            else
                            {
                                viewport.Y = offsetList[offsetList.Count-1];
                            }

                            // and remove offsets before the matching one -
                            // they'll never be needed again
                            offsetList.RemoveRange(0, index);
                        }

                        // if the list is no longer needed, discard it
                        if (index < 0 || offsetList.Count <= 1)
                        {
                            EffectiveOffsetInformationField.ClearValue(container);
                        }
                    }
                }
            }
            else
            {
                viewport = new Rect(0, 0, constraint.Width, constraint.Height);

                if (isHorizontal)
                {
                    viewport.Width = Double.PositiveInfinity;
                }
                else
                {
                    viewport.Height = Double.PositiveInfinity;
                }
            }

            // Adjust extendedViewport

            extendedViewport = _extendedViewport;

            if (isHorizontal)
            {
                extendedViewport.X += viewport.X - _viewport.X;
            }
            else
            {
                extendedViewport.Y += viewport.Y - _viewport.Y;
            }
        }
        /// <summary>
        /// Initializes the viewport for this panel.
        /// </summary>
        private void InitializeViewport(
            object parentItem,
            IContainItemStorage parentItemStorageProvider,
            IHierarchicalVirtualizationAndScrollInfo virtualizationInfoProvider,
            bool isHorizontal,
            Size constraint,
            ref Rect viewport,
            ref VirtualizationCacheLength cacheSize,
            ref VirtualizationCacheLengthUnit cacheUnit,
            out Rect extendedViewport)
        {

            Size extent = new Size();
            bool isVSP45Compat = IsVSP45Compat;

            if (IsScrolling)
            {
                //
                // We're the top level scrolling panel. Fetch the offset from the _scrollData.
                //

                Size size;
                double offsetX, offsetY;
                Size viewportSize;

                size = constraint;
                offsetX = _scrollData._offset.X;
                offsetY = _scrollData._offset.Y;
                extent = _scrollData._extent;
                viewportSize = _scrollData._viewport;

                if (!IsScrollActive || IgnoreMaxDesiredSize)
                {
                    _scrollData._maxDesiredSize = new Size();
                }

                if (IsPixelBased)
                {
                    viewport = new Rect(offsetX, offsetY, size.Width, size.Height);
                    CoerceScrollingViewportOffset(ref viewport, extent, isHorizontal);
                }
                else
                {
                    viewport = new Rect(offsetX, offsetY, viewportSize.Width, viewportSize.Height);
                    CoerceScrollingViewportOffset(ref viewport, extent, isHorizontal);
                    viewport.Size = size;
                }

                if (IsVirtualizing)
                {
                    cacheSize = VirtualizingStackPanel.GetCacheLength(this);
                    cacheUnit = VirtualizingStackPanel.GetCacheLengthUnit(this);

                    if (DoubleUtil.GreaterThan(cacheSize.CacheBeforeViewport, 0) ||
                        DoubleUtil.GreaterThan(cacheSize.CacheAfterViewport, 0))
                    {
                        if (!MeasureCaches)
                        {
                            WasLastMeasurePassAnchored = (_firstContainerInViewport != null) || (_bringIntoViewLeafContainer != null);

                            DispatcherOperation measureCachesOperation = MeasureCachesOperationField.GetValue(this);
                            if (measureCachesOperation == null)
                            {
                                Action measureCachesAction = null;
                                int retryCount = 3;
                                measureCachesAction = (Action)delegate()
                                    {
                                        Debug.Assert(retryCount >=0, "retry MeasureCaches too often");
                                        bool isLayoutDirty = (0 < retryCount--) && (MeasureDirty || ArrangeDirty);
                                        try
                                        {
                                            if (isVSP45Compat || !isLayoutDirty)
                                            {
                                                MeasureCachesOperationField.ClearValue(this);

                                                MeasureCaches = true;

                                                if (WasLastMeasurePassAnchored)
                                                {
                                                    SetAnchorInformation(isHorizontal);
                                                }

                                                InvalidateMeasure();
                                                UpdateLayout();
                                            }
                                        }
                                        finally
                                        {
                                            // check whether UpdateLayout finished the job
                                            isLayoutDirty = isLayoutDirty ||
                                                    ((0 < retryCount) && (MeasureDirty || ArrangeDirty));
                                            if (!isVSP45Compat && isLayoutDirty)
                                            {
                                                // try the measure-cache pass again later.
                                                // Note that we only do this when:
                                                // 1. this VSP's layout is dirty, either because
                                                //    a. it was dirty to begin with so we
                                                //       skipped UpdateLayout, or
                                                //    b. UpdateLayout ran, but left this VSP's
                                                //       layout dirty.
                                                // 2. we haven't run out of retries
                                                // 3. we're not in 4.5-compat mode
                                                //
                                                // (1) can happen if layout times out and moves to
                                                //     background.
                                                // (2) protects against loops when an app calls
                                                //     VSP.Measure directly, outside of the normal
                                                //     layout system (real appps don't do this,
                                                //     but test code does - it happens in the DrtXaml test).
                                                // (3) preserves compat with 4.5RTM, where the
                                                //     "move to background" situation led to an
                                                //     infinite loop.
                                                MeasureCachesOperationField.SetValue(this,
                                                    Dispatcher.BeginInvoke(DispatcherPriority.Background, measureCachesAction));
                                            }

                                            MeasureCaches = false;

                                            // If there is a pending anchor operation that got registered in
                                            // the current pass, or if layout didn't finish, we don't want to
                                            // clear the IsScrollActive flag.
                                            // We should allow that measure pass to also settle and then clear
                                            // the flag.

                                            DispatcherOperation anchoredInvalidateMeasureOperation = AnchoredInvalidateMeasureOperationField.GetValue(this);
                                            if (anchoredInvalidateMeasureOperation == null && (isVSP45Compat || !isLayoutDirty))
                                            {
                                                if (isVSP45Compat)
                                                {
                                                    IsScrollActive = false;
                                                }
                                                else if (IsScrollActive)
                                                {
                                                    // keep IsScrollActive set until the
                                                    // anchored measure has occurred.  It may
                                                    // need to remeasure, which should count
                                                    // as part of the scroll operation
                                                    DispatcherOperation clearIsScrollActiveOperation = ClearIsScrollActiveOperationField.GetValue(this);
                                                    if (clearIsScrollActiveOperation != null)
                                                    {
                                                        clearIsScrollActiveOperation.Abort();
                                                    }
                                                    clearIsScrollActiveOperation = Dispatcher.BeginInvoke(DispatcherPriority.Background,
                                                        (Action)ClearIsScrollActive);

                                                    ClearIsScrollActiveOperationField.SetValue(this, clearIsScrollActiveOperation);
                                                }
                                            }
                                        }
                                    };
                                measureCachesOperation = Dispatcher.BeginInvoke(DispatcherPriority.Background,
                                                                                measureCachesAction);
                                MeasureCachesOperationField.SetValue(this, measureCachesOperation);
                            }
                        }
                    }
                    else if (IsScrollActive)
                    {
                        DispatcherOperation clearIsScrollActiveOperation = ClearIsScrollActiveOperationField.GetValue(this);
                        if (clearIsScrollActiveOperation == null)
                        {
                            clearIsScrollActiveOperation = Dispatcher.BeginInvoke(DispatcherPriority.Background,
                                (Action)ClearIsScrollActive);

                            ClearIsScrollActiveOperationField.SetValue(this, clearIsScrollActiveOperation);
                        }
                    }

                    NormalizeCacheLength(isHorizontal, viewport, ref cacheSize, ref cacheUnit);
                }
                else
                {
                    cacheSize = new VirtualizationCacheLength(
                        Double.PositiveInfinity,
                        IsViewportEmpty(isHorizontal, viewport) ?
                        0.0 :
                        Double.PositiveInfinity);
                    cacheUnit = VirtualizationCacheLengthUnit.Pixel;

                    ClearAsyncOperations();
                }
            }
            else if (virtualizationInfoProvider != null)
            {
                //
                // Adjust the viewport offset for a non scrolling panel to account for the HeaderSize
                // when virtualizing.
                //
                HierarchicalVirtualizationConstraints virtualizationConstraints = virtualizationInfoProvider.Constraints;
                viewport = virtualizationConstraints.Viewport;
                cacheSize = virtualizationConstraints.CacheLength;
                cacheUnit = virtualizationConstraints.CacheLengthUnit;
                MeasureCaches = virtualizationInfoProvider.InBackgroundLayout;

                if (isVSP45Compat)
                {
                    AdjustNonScrollingViewportForHeader(virtualizationInfoProvider, ref viewport, ref cacheSize, ref cacheUnit);
                }
                else
                {
                    AdjustNonScrollingViewportForInset(isHorizontal, parentItem, parentItemStorageProvider, virtualizationInfoProvider, ref viewport, ref cacheSize, ref cacheUnit);
                }
            }
            else
            {
                viewport = new Rect(0, 0, constraint.Width, constraint.Height);

                if (isHorizontal)
                {
                    viewport.Width = Double.PositiveInfinity;
                }
                else
                {
                    viewport.Height = Double.PositiveInfinity;
                }
            }

            // Adjust extendedViewport

            extendedViewport = _extendedViewport;

            if (isHorizontal)
            {
                extendedViewport.X += viewport.X - _viewport.X;
            }
            else
            {
                extendedViewport.Y += viewport.Y - _viewport.Y;
            }
        }
Beispiel #15
0
        private void NormalizeCacheLength(
            bool isHorizontal,
            Rect viewport,
            ref VirtualizationCacheLength cacheLength,
            ref VirtualizationCacheLengthUnit cacheUnit)
        {
            if (cacheUnit == VirtualizationCacheLengthUnit.Page)
            {
                double factor = isHorizontal ? viewport.Width : viewport.Height;

                if (Double.IsPositiveInfinity(factor))
                {
                    cacheLength = new VirtualizationCacheLength(
                        0,
                        0);
                }
                else
                {
                    cacheLength = new VirtualizationCacheLength(
                        cacheLength.CacheBeforeViewport * factor,
                        cacheLength.CacheAfterViewport * factor);
                }

                cacheUnit = VirtualizationCacheLengthUnit.Pixel;
            }
        }
Beispiel #16
0
        /// <summary>
        /// Initializes the viewport for this panel.
        /// </summary>
        private void InitializeViewport(
            IHierarchicalVirtualizationAndScrollInfo virtualizationInfoProvider,
            bool isHorizontal,
            Size constraint,
            ref Rect viewport,
            ref VirtualizationCacheLength cacheSize,
            ref VirtualizationCacheLengthUnit cacheUnit,
            out Rect extendedViewport)
        {

            Size extent = new Size();

            if (IsScrolling)
            {
                //
                // We're the top level scrolling panel. Fetch the offset from the _scrollData.
                //

                Size size;
                double offsetX, offsetY;
                Size viewportSize;

                size = constraint;
                offsetX = _scrollData._offset.X;
                offsetY = _scrollData._offset.Y;
                extent = _scrollData._extent;
                viewportSize = _scrollData._viewport;

                if (!IsScrollActive || IgnoreMaxDesiredSize)
                {
                    _scrollData._maxDesiredSize = new Size();
                }

                if (IsPixelBased)
                {
                    viewport = new Rect(offsetX, offsetY, size.Width, size.Height);
                    CoerceScrollingViewportOffset(ref viewport, extent, isHorizontal);
                }
                else
                {
                    viewport = new Rect(offsetX, offsetY, viewportSize.Width, viewportSize.Height);
                    CoerceScrollingViewportOffset(ref viewport, extent, isHorizontal);
                    viewport.Size = size;
                }

                if (IsVirtualizing)
                {
                    cacheSize = VirtualizingStackPanel.GetCacheLength(this);
                    cacheUnit = VirtualizingStackPanel.GetCacheLengthUnit(this);

                    if (DoubleUtil.GreaterThan(cacheSize.CacheBeforeViewport, 0) ||
                        DoubleUtil.GreaterThan(cacheSize.CacheAfterViewport, 0))
                    {
                        if (!MeasureCaches)
                        {
                            WasLastMeasurePassAnchored = (_firstContainerInViewport != null) || (_bringIntoViewLeafContainer != null);

                            DispatcherOperation measureCachesOperation = MeasureCachesOperationField.GetValue(this);
                            if (measureCachesOperation == null)
                            {
                                measureCachesOperation = Dispatcher.BeginInvoke(DispatcherPriority.Background,
                                    (Action)delegate()
                                    {
                                        try
                                        {
                                            MeasureCachesOperationField.ClearValue(this);

                                            MeasureCaches = true;

                                            if (WasLastMeasurePassAnchored)
                                            {
                                                SetAnchorInformation(isHorizontal);
                                            }

                                            InvalidateMeasure();
                                            UpdateLayout();
                                        }
                                        finally
                                        {
                                            MeasureCaches = false;

                                            // If there is a pending anchor operation that got registered in
                                            // the current pass, we dont want to clear the IsScrollActive flag.
                                            // We should allow that measure pass to also settle and then clear
                                            // the flag.

                                            DispatcherOperation anchoredInvalidateMeasureOperation = AnchoredInvalidateMeasureOperationField.GetValue(this);
                                            if (anchoredInvalidateMeasureOperation == null)
                                            {
                                                IsScrollActive = false;
                                            }
                                        }
                                    });

                                MeasureCachesOperationField.SetValue(this, measureCachesOperation);
                            }
                        }
                    }
                    else if (IsScrollActive)
                    {
                        DispatcherOperation clearIsScrollActiveOperation = ClearIsScrollActiveOperationField.GetValue(this);
                        if (clearIsScrollActiveOperation == null)
                        {
                            clearIsScrollActiveOperation = Dispatcher.BeginInvoke(DispatcherPriority.Background,
                                (Action)delegate()
                                {
                                    ClearIsScrollActiveOperationField.ClearValue(this);
                                    IsScrollActive = false;
                                });

                            ClearIsScrollActiveOperationField.SetValue(this, clearIsScrollActiveOperation);
                        }
                    }

                    NormalizeCacheLength(isHorizontal, viewport, ref cacheSize, ref cacheUnit);
                }
                else
                {
                    cacheSize = new VirtualizationCacheLength(
                        Double.PositiveInfinity,
                        IsViewportEmpty(isHorizontal, viewport) ?
                        0.0 :
                        Double.PositiveInfinity);
                    cacheUnit = VirtualizationCacheLengthUnit.Pixel;

                    ClearAsyncOperations();
                }
            }
            else if (virtualizationInfoProvider != null)
            {
                //
                // Adjust the viewport offset for a non scrolling panel to account for the HeaderSize
                // when virtualizing.
                //
                HierarchicalVirtualizationConstraints virtualizationConstraints = virtualizationInfoProvider.Constraints;
                viewport = virtualizationConstraints.Viewport;
                cacheSize = virtualizationConstraints.CacheLength;
                cacheUnit = virtualizationConstraints.CacheLengthUnit;
                MeasureCaches = virtualizationInfoProvider.InBackgroundLayout;

                AdjustNonScrollingViewportForHeader(virtualizationInfoProvider, ref viewport, ref cacheSize, ref cacheUnit);
            }
            else
            {
                viewport = new Rect(0, 0, constraint.Width, constraint.Height);

                if (isHorizontal)
                {
                    viewport.Width = Double.PositiveInfinity;
                }
                else
                {
                    viewport.Height = Double.PositiveInfinity;
                }
            }

            // Adjust extendedViewport

            extendedViewport = _extendedViewport;

            if (isHorizontal)
            {
                extendedViewport.X += viewport.X - _viewport.X;
            }
            else
            {
                extendedViewport.Y += viewport.Y - _viewport.Y;
            }
        }
 public static void SetCacheLengthUnit(DependencyObject element, VirtualizationCacheLengthUnit unit)
 {
     NoesisGUI_PINVOKE.VirtualizingPanel_SetCacheLengthUnit(DependencyObject.getCPtr(element), (int)unit);
 }
        public static VirtualizationCacheLengthUnit GetCacheLengthUnit(DependencyObject element)
        {
            VirtualizationCacheLengthUnit ret = (VirtualizationCacheLengthUnit)NoesisGUI_PINVOKE.VirtualizingPanel_GetCacheLengthUnit(DependencyObject.getCPtr(element));

            return(ret);
        }
Beispiel #19
0
        }// *** END DEAD CODE ***

        /// <summary>
        /// Adjusts viewport to accommodate the inset.
        /// </summary>
        private void AdjustNonScrollingViewportForInset(
            bool isHorizontal,
            object parentItem,
            IContainItemStorage parentItemStorageProvider,
            IHierarchicalVirtualizationAndScrollInfo virtualizationInfoProvider,
            ref Rect viewport,
            ref VirtualizationCacheLength cacheLength,
            ref VirtualizationCacheLengthUnit cacheUnit)
        {
            // Recall that a viewport-rect has location (X,Y) expressed in scroll units
            // (pixels or items), but size (Width,Height) expressed in pixels and
            // describing the available size - previous contributions have been
            // deducted.
            Rect parentViewport = viewport;
            FrameworkElement container = virtualizationInfoProvider as FrameworkElement;
            Thickness inset = GetItemsHostInsetForChild(virtualizationInfoProvider, parentItemStorageProvider, parentItem);
            bool isHeaderBeforeItems = IsHeaderBeforeItems(isHorizontal, container, ref inset);
            double cacheBeforeSize = cacheLength.CacheBeforeViewport;
            double cacheAfterSize = cacheLength.CacheAfterViewport;

            // offset the viewport by the inset, along the scrolling axis
            if (isHorizontal)
            {
                viewport.X -= IsPixelBased ? inset.Left : isHeaderBeforeItems ? 1 : 0;
            }
            else
            {
                viewport.Y -= IsPixelBased ? inset.Top : isHeaderBeforeItems ? 1 : 0;
            }

            if (isHorizontal)
            {
                if (DoubleUtil.GreaterThan(parentViewport.X, 0))
                {
                    // Viewport is after start of this container

                    if (DoubleUtil.GreaterThan(viewport.Width, 0))
                    {
                        // Viewport is not yet full - we're delving for the first
                        // container in the viewport.  We're moving forward, so
                        // do not contribute to cache-after (we won't know whether
                        // this container needs to contribute to cache-after until
                        // after measuring this panel).

                        if (IsPixelBased && DoubleUtil.GreaterThan(0, viewport.X))
                        {
                            // Viewport starts within the leading inset

                            // The inset is split in two pieces by the viewport leading edge.
                            // The first piece contributes to the cache-before;
                            // its width is parentViewport.X
                            if (cacheUnit == VirtualizationCacheLengthUnit.Pixel)
                            {
                                cacheBeforeSize = Math.Max(0, cacheBeforeSize - parentViewport.X);
                            }

                            // The second piece contributes to the viewport itself;
                            // its width is (inset.Left - parentViewport.X) = -viewport.X
                            viewport.Width = Math.Max(0, viewport.Width + viewport.X);
                        }
                        else
                        {
                            // Viewport starts after the leading inset.

                            // The contributions due to this container cannot be
                            // determined yet.  These are (a) leading inset to
                            // cache-before, (b) trailing inset to viewport and/or
                            // cache-after.
                        }
                    }
                    else
                    {
                        // viewport is full (and starts after this container).
                        // We're filling the cache-before back-to-front.

                        // The trailing inset contributes to cache-before
                        if (cacheUnit == VirtualizationCacheLengthUnit.Pixel)
                        {
                            cacheBeforeSize = Math.Max(0, cacheBeforeSize - inset.Right);
                        }
                        else if (!isHeaderBeforeItems)
                        {
                            cacheBeforeSize = Math.Max(0, cacheBeforeSize - 1);
                        }
                    }
                }

                else if (DoubleUtil.GreaterThan(viewport.Width, 0))
                {
                    // Viewport has available space (and starts before this container)
                    // We are filling the viewport front-to-back.

                    if (DoubleUtil.GreaterThanOrClose(viewport.Width, inset.Left))
                    {
                        // Viewport has room for the entire leading inset.

                        // Leading inset contributes to viewport
                        viewport.Width = Math.Max(0, viewport.Width - inset.Left);
                    }
                    else
                    {
                        // Leading inset exhausts the remaining available space.

                        // The inset is split into two pieces (by the viewport trailing edge).
                        // The second piece contributes to the cache-after;
                        // its width is (inset.Left - viewport.Width)
                        if (cacheUnit == VirtualizationCacheLengthUnit.Pixel)
                        {
                            cacheAfterSize = Math.Max(0, cacheAfterSize - (inset.Left - viewport.Width));
                        }

                        // The first piece contributes to the viewport itself;
                        // its width is viewport.Width (enough to decrease available width to zero)
                        viewport.Width = 0;
                    }
                }

                else
                {
                    // Viewport has no available space (and starts before this container).
                    // We are filling the cache-after front-to-back.

                    // The leading inset contributes to cache-after
                    if (cacheUnit == VirtualizationCacheLengthUnit.Pixel)
                    {
                        cacheAfterSize = Math.Max(0, cacheAfterSize - inset.Left);
                    }
                    else if (isHeaderBeforeItems)
                    {
                        cacheAfterSize = Math.Max(0, cacheAfterSize - 1);
                    }
                }
            }
            else    // scroll axis is vertical
            {
                if (DoubleUtil.GreaterThan(parentViewport.Y, 0))
                {
                    // Viewport is after start of this container

                    if (DoubleUtil.GreaterThan(viewport.Height, 0))
                    {
                        // Viewport is not yet full - we're delving for the first
                        // container in the viewport.  We're moving forward, so
                        // do not contribute to cache-after (we won't know whether
                        // this container needs to contribute to cache-after until
                        // after measuring this panel).

                        if (IsPixelBased && DoubleUtil.GreaterThan(0, viewport.Y))
                        {
                            // Viewport starts within the leading inset

                            // The inset is split in two pieces by the viewport leading edge.
                            // The first piece contributes to the cache-before;
                            // its height is parentViewport.Y
                            if (cacheUnit == VirtualizationCacheLengthUnit.Pixel)
                            {
                                cacheBeforeSize = Math.Max(0, cacheBeforeSize - parentViewport.Y);
                            }

                            // The second piece contributes to the viewport itself;
                            // its height is (inset.Top - parentViewport.Y) = -viewport.Y
                            viewport.Height = Math.Max(0, viewport.Height + viewport.Y);
                        }
                        else
                        {
                            // Viewport starts after the leading inset.

                            // The contributions due to this container cannot be
                            // determined yet.  These are (a) leading inset to
                            // cache-before, (b) trailing inset to viewport and/or
                            // cache-after.
                        }
                    }
                    else
                    {
                        // viewport is full (and starts after this container).
                        // We're filling the cache-before back-to-front.

                        // The trailing inset contributes to cache-before
                        if (cacheUnit == VirtualizationCacheLengthUnit.Pixel)
                        {
                            cacheBeforeSize = Math.Max(0, cacheBeforeSize - inset.Bottom);
                        }
                        else if (!isHeaderBeforeItems)
                        {
                            cacheBeforeSize = Math.Max(0, cacheBeforeSize - 1);
                        }
                    }
                }

                else if (DoubleUtil.GreaterThan(viewport.Height, 0))
                {
                    // Viewport has available space (and starts before this container)
                    // We are filling the viewport front-to-back.

                    if (DoubleUtil.GreaterThanOrClose(viewport.Height, inset.Top))
                    {
                        // Viewport has room for the entire leading inset.

                        // Leading inset contributes to viewport
                        viewport.Height = Math.Max(0, viewport.Height - inset.Top);
                    }
                    else
                    {
                        // Leading inset exhausts the remaining available space.

                        // The inset is split into two pieces (by the viewport trailing edge).
                        // The second piece contributes to the cache-after;
                        // its height is (inset.Top - viewport.Height)
                        if (cacheUnit == VirtualizationCacheLengthUnit.Pixel)
                        {
                            cacheAfterSize = Math.Max(0, cacheAfterSize - (inset.Top - viewport.Height));
                        }

                        // The first piece contributes to the viewport itself;
                        // its height is viewport.Height (enough to decrease available height to zero)
                        viewport.Height = 0;
                    }
                }

                else
                {
                    // Viewport has no available space (and starts before this container).
                    // We are filling the cache-after front-to-back.

                    // The leading inset contributes to cache-after
                    if (cacheUnit == VirtualizationCacheLengthUnit.Pixel)
                    {
                        cacheAfterSize = Math.Max(0, cacheAfterSize - inset.Top);
                    }
                    else if (isHeaderBeforeItems)
                    {
                        cacheAfterSize = Math.Max(0, cacheAfterSize - 1);
                    }
                }
            }

            // apply the cache adjustment
            cacheLength = new VirtualizationCacheLength(cacheBeforeSize, cacheAfterSize);
        }
Beispiel #20
0
        }// *** End DEAD CODE ***

        private void GetSizesForChildWithInset(
            bool isHorizontal,
            bool isChildHorizontal,
            bool isBeforeFirstItem,
            bool isAfterLastItem,
            IHierarchicalVirtualizationAndScrollInfo virtualizingChild,
            Size childDesiredSize,
            Rect childViewport,
            VirtualizationCacheLength childCacheSize,
            VirtualizationCacheLengthUnit childCacheUnit,
            out Size childPixelSize,
            out Size childPixelSizeInViewport,
            out Size childPixelSizeInCacheBeforeViewport,
            out Size childPixelSizeInCacheAfterViewport,
            out Size childLogicalSize,
            out Size childLogicalSizeInViewport,
            out Size childLogicalSizeInCacheBeforeViewport,
            out Size childLogicalSizeInCacheAfterViewport)
        {
            // set childPixelSize to childDesiredSize directly.   Ideally this should
            // be the same as adding the contributions from the items panel and
            // the front and back insets, as indicated by commented-out lines below,
            // but this isn't true when the inset is merely an estimate (i.e.
            // before the child has been arranged) - contributions from margins,
            // border thickness, etc. between the items panel and the virtualizingChild
            // are not yet accounted for.  The childDesiredSize is more accurate,
            // so we use that.
            childPixelSize = childDesiredSize;
            childPixelSizeInViewport = new Size();
            childPixelSizeInCacheBeforeViewport = new Size();
            childPixelSizeInCacheAfterViewport = new Size();

            childLogicalSize = new Size();
            childLogicalSizeInViewport = new Size();
            childLogicalSizeInCacheBeforeViewport = new Size();
            childLogicalSizeInCacheAfterViewport = new Size();

            HierarchicalVirtualizationItemDesiredSizes itemDesiredSizes =
                (virtualizingChild != null) ? virtualizingChild.ItemDesiredSizes
                                            : new HierarchicalVirtualizationItemDesiredSizes();

            // the interesting case is when there is nested virtualization.  It's not
            // enough to test whether virtualizingChild is non-null;  the child
            // may not have done any virtualization (eg. because its ItemsHost
            // is not a VSP).  Instead, test whether its ItemsHost recorded a
            // nonzero extent.
            if ((!isHorizontal &&  (itemDesiredSizes.PixelSize.Height > 0 ||
                                    itemDesiredSizes.LogicalSize.Height > 0)) ||
                ( isHorizontal &&  (itemDesiredSizes.PixelSize.Width > 0 ||
                                    itemDesiredSizes.LogicalSize.Width > 0)))
            {
                // itemDesiredSizes gives the contribution from the nested panel.
              //StackSizes(isHorizontal, ref childPixelSize, itemDesiredSizes.PixelSize); (omitted - see comment at initialization)
                StackSizes(isHorizontal, ref childPixelSizeInCacheBeforeViewport, itemDesiredSizes.PixelSizeBeforeViewport);
                StackSizes(isHorizontal, ref childPixelSizeInViewport, itemDesiredSizes.PixelSizeInViewport);
                StackSizes(isHorizontal, ref childPixelSizeInCacheAfterViewport, itemDesiredSizes.PixelSizeAfterViewport);

                StackSizes(isHorizontal, ref childLogicalSize, itemDesiredSizes.LogicalSize);
                StackSizes(isHorizontal, ref childLogicalSizeInCacheBeforeViewport, itemDesiredSizes.LogicalSizeBeforeViewport);
                StackSizes(isHorizontal, ref childLogicalSizeInViewport, itemDesiredSizes.LogicalSizeInViewport);
                StackSizes(isHorizontal, ref childLogicalSizeInCacheAfterViewport, itemDesiredSizes.LogicalSizeAfterViewport);

                // Now add the contributions from the inset.  First decide whether
                // the child's item belongs to the front or back inset
                Thickness inset = GetItemsHostInsetForChild(virtualizingChild);
                bool isHeaderBeforeItems = IsHeaderBeforeItems(isHorizontal, virtualizingChild as FrameworkElement, ref inset);

                // Add contributions from the front inset.
                Size frontPixelSize = isHorizontal ? new Size(Math.Max(inset.Left,0), childDesiredSize.Height)
                                                   : new Size(childDesiredSize.Width, Math.Max(inset.Top, 0));
                Size frontLogicalSize = isHeaderBeforeItems ? new Size(1,1) : new Size(0,0);

              //StackSizes(isHorizontal, ref childPixelSize, frontPixelSize); (omitted - see comment at initialization)
                StackSizes(isHorizontal, ref childLogicalSize, frontLogicalSize);
                GetSizesForChildIntersectingTheViewport(isHorizontal, isChildHorizontal,
                    frontPixelSize, frontLogicalSize,
                    childViewport,
                    ref childPixelSizeInViewport, ref childLogicalSizeInViewport,
                    ref childPixelSizeInCacheBeforeViewport, ref childLogicalSizeInCacheBeforeViewport,
                    ref childPixelSizeInCacheAfterViewport, ref childLogicalSizeInCacheAfterViewport);

                // Add contributions from the back inset.
                Size backPixelSize = isHorizontal ? new Size(Math.Max(inset.Right,0), childDesiredSize.Height)
                                                   : new Size(childDesiredSize.Width, Math.Max(inset.Bottom,0));
                Size backLogicalSize = isHeaderBeforeItems ? new Size(0,0) : new Size(1,1);

              //StackSizes(isHorizontal, ref childPixelSize, backPixelSize); (omitted - see comment at initialization)
                StackSizes(isHorizontal, ref childLogicalSize, backLogicalSize);

                // before calling the helper, adjust the viewport to account for
                // the contributions we've just made
                Rect adjustedChildViewport = childViewport;
                if (isHorizontal)
                {
                    adjustedChildViewport.X -= IsPixelBased ? frontPixelSize.Width + itemDesiredSizes.PixelSize.Width
                                                            : frontLogicalSize.Width + itemDesiredSizes.LogicalSize.Width;
                    adjustedChildViewport.Width = Math.Max(0, adjustedChildViewport.Width - childPixelSizeInViewport.Width);
                }
                else
                {
                    adjustedChildViewport.Y -= IsPixelBased ? frontPixelSize.Height + itemDesiredSizes.PixelSize.Height
                                                            : frontLogicalSize.Height + itemDesiredSizes.LogicalSize.Height;
                    adjustedChildViewport.Height = Math.Max(0, adjustedChildViewport.Height - childPixelSizeInViewport.Height);
                }
                GetSizesForChildIntersectingTheViewport(isHorizontal, isChildHorizontal,
                    backPixelSize, backLogicalSize,
                    adjustedChildViewport,
                    ref childPixelSizeInViewport, ref childLogicalSizeInViewport,
                    ref childPixelSizeInCacheBeforeViewport, ref childLogicalSizeInCacheBeforeViewport,
                    ref childPixelSizeInCacheAfterViewport, ref childLogicalSizeInCacheAfterViewport);
            }
            else
            {
                // there was no nested virtualization.  The only contributions come
                // directly from the given child.

              //childPixelSize = childDesiredSize; (already done at initialization)
                childLogicalSize = new Size(1, 1);

                if (isBeforeFirstItem)
                {
                    childPixelSizeInCacheBeforeViewport = childDesiredSize;
                    childLogicalSizeInCacheBeforeViewport = new Size(DoubleUtil.GreaterThan(childPixelSizeInCacheBeforeViewport.Width, 0) ? 1 : 0,
                                                                     DoubleUtil.GreaterThan(childPixelSizeInCacheBeforeViewport.Height, 0) ? 1 : 0);
                }
                else if (isAfterLastItem)
                {
                    childPixelSizeInCacheAfterViewport = childDesiredSize;
                    childLogicalSizeInCacheAfterViewport = new Size(DoubleUtil.GreaterThan(childPixelSizeInCacheAfterViewport.Width, 0) ? 1 : 0,
                                                                    DoubleUtil.GreaterThan(childPixelSizeInCacheAfterViewport.Height, 0) ? 1 : 0);
                }
                else
                {
                    GetSizesForChildIntersectingTheViewport(
                        isHorizontal,
                        isChildHorizontal,
                        childPixelSize,
                        childLogicalSize,
                        childViewport,
                        ref childPixelSizeInViewport,
                        ref childLogicalSizeInViewport,
                        ref childPixelSizeInCacheBeforeViewport,
                        ref childLogicalSizeInCacheBeforeViewport,
                        ref childPixelSizeInCacheAfterViewport,
                        ref childLogicalSizeInCacheAfterViewport);
                }
            }
        }
Beispiel #21
0
        public static IntPtr Box_VirtualizationCacheLengthUnit(VirtualizationCacheLengthUnit val)
        {
            IntPtr ret = NoesisGUI_PINVOKE.Box_VirtualizationCacheLengthUnit((int)val);

            return(ret);
        }
        /// <summary>
        ///     Sets the value for <see cref="CacheLengthUnitProperty" />.
        /// </summary>
        /// <param name="element">The element on which to set the value.</param>
        /// <param name="value">The CacheLenghtUnit for the matching CacheLength property.</param>
        public static void SetCacheLengthUnit(DependencyObject element, VirtualizationCacheLengthUnit value)
        {
            if (element == null)
            {
                throw new ArgumentNullException("element");
            }

            element.SetValue(CacheLengthUnitProperty, value);
        }
Beispiel #23
0
 /// <summary>
 /// Adjusts viewport to accomodate the items.
 /// </summary>
 private void AdjustNonScrollingViewportForItems(IHierarchicalVirtualizationAndScrollInfo virtualizationInfoProvider,
                                                     ref Rect viewport,
                                                     ref VirtualizationCacheLength cacheLength,
                                                     ref VirtualizationCacheLengthUnit cacheLengthUnit)
 {
     bool forHeader = false;
     AdjustNonScrollingViewport(virtualizationInfoProvider, ref viewport, ref cacheLength, ref cacheLengthUnit, forHeader);
 }
Beispiel #24
0
        /// <summary>
        /// Adjusts viewport to accomodate the either the Header or ItemsPanel.
        /// </summary>
        private void AdjustNonScrollingViewport(
            IHierarchicalVirtualizationAndScrollInfo virtualizationInfoProvider,
            ref Rect viewport,
            ref VirtualizationCacheLength cacheLength,
            ref VirtualizationCacheLengthUnit cacheUnit,
            bool forHeader)
        {
            Debug.Assert(virtualizationInfoProvider != null, "This method should only be invoked for a virtualizing owner");
            Debug.Assert(cacheUnit != VirtualizationCacheLengthUnit.Page, "Page after cache size is not expected here.");

            Rect parentViewport = viewport;
            double sizeAfterStartViewportEdge = 0;
            double sizeBeforeStartViewportEdge = 0;
            double sizeAfterEndViewportEdge = 0;
            double sizeBeforeEndViewportEdge = 0;
            double cacheBeforeSize = cacheLength.CacheBeforeViewport;
            double cacheAfterSize = cacheLength.CacheAfterViewport;

            HierarchicalVirtualizationHeaderDesiredSizes headerDesiredSizes = virtualizationInfoProvider.HeaderDesiredSizes;
            HierarchicalVirtualizationItemDesiredSizes itemDesiredSizes = virtualizationInfoProvider.ItemDesiredSizes;

            Size pixelSize = forHeader ? headerDesiredSizes.PixelSize : itemDesiredSizes.PixelSize;
            Size logicalSize = forHeader ? headerDesiredSizes.LogicalSize : itemDesiredSizes.LogicalSize;

            RelativeHeaderPosition headerPosition = RelativeHeaderPosition.Top; // virtualizationInfoProvider.RelativeHeaderPosition;

            if ((forHeader && headerPosition == RelativeHeaderPosition.Left) ||
                (!forHeader && headerPosition == RelativeHeaderPosition.Right))
            {
                //
                // Adjust the offset
                //

                viewport.X -= IsPixelBased ? pixelSize.Width : logicalSize.Width;

                if (DoubleUtil.GreaterThan(parentViewport.X, 0))
                {
                    //
                    // Viewport is after the start of this panel
                    //

                    if (IsPixelBased && DoubleUtil.GreaterThan(pixelSize.Width, parentViewport.X))
                    {
                        //
                        // Header straddles the start edge of the viewport
                        //

                        sizeAfterStartViewportEdge = pixelSize.Width - parentViewport.X;
                        sizeBeforeStartViewportEdge = pixelSize.Width - sizeAfterStartViewportEdge;

                        viewport.Width = Math.Max(viewport.Width - sizeAfterStartViewportEdge, 0);

                        if (cacheUnit == VirtualizationCacheLengthUnit.Pixel)
                        {
                            cacheBeforeSize = Math.Max(cacheBeforeSize - sizeBeforeStartViewportEdge, 0);
                        }
                        else
                        {
                            cacheBeforeSize = Math.Max(cacheBeforeSize - Math.Floor(logicalSize.Width * sizeBeforeStartViewportEdge / pixelSize.Width), 0);
                        }
                    }
                    else
                    {
                        //
                        // Header is completely before the start edge of the viewport. We do not need to
                        // adjust the cacheBefore size in this case because the cacheBefore is populated
                        // bottom up and we cant really be certain that the header will infact lie within the
                        // cacheBefore region.
                        //
                    }
                }
                else
                {
                    //
                    // Viewport is at or before this panel
                    //

                    if (DoubleUtil.GreaterThan(parentViewport.Width, 0))
                    {
                        if (DoubleUtil.GreaterThanOrClose(parentViewport.Width, pixelSize.Width))
                        {
                            //
                            // Header is completely within the viewport
                            //

                            viewport.Width = Math.Max(0, parentViewport.Width - pixelSize.Width);
                        }
                        else
                        {
                            //
                            // Header straddles the end edge of the viewport
                            //

                            sizeBeforeEndViewportEdge = parentViewport.Width;
                            sizeAfterEndViewportEdge = pixelSize.Width - sizeBeforeEndViewportEdge;

                            viewport.Width = 0;

                            if (cacheUnit == VirtualizationCacheLengthUnit.Pixel)
                            {
                                cacheAfterSize = Math.Max(cacheAfterSize - sizeAfterEndViewportEdge, 0);
                            }
                            else
                            {
                                cacheAfterSize = Math.Max(cacheAfterSize - Math.Floor(logicalSize.Width * sizeAfterEndViewportEdge / pixelSize.Width), 0);
                            }
                        }
                    }
                    else
                    {
                        //
                        // Header is completely after the end edge of the viewport
                        //

                        if (cacheUnit == VirtualizationCacheLengthUnit.Pixel)
                        {
                            cacheAfterSize = Math.Max(cacheAfterSize - pixelSize.Width, 0);
                        }
                        else
                        {
                            cacheAfterSize = Math.Max(cacheAfterSize - logicalSize.Width, 0);
                        }
                    }
                }
            }
            else if ((forHeader && headerPosition == RelativeHeaderPosition.Top) ||
                    (!forHeader && headerPosition == RelativeHeaderPosition.Bottom))
            {
                //
                // Adjust the offset
                //

                viewport.Y -= IsPixelBased ? pixelSize.Height : logicalSize.Height;

                if (DoubleUtil.GreaterThan(parentViewport.Y, 0))
                {
                    //
                    // Viewport is after the start of this panel
                    //

                    if (IsPixelBased && DoubleUtil.GreaterThan(pixelSize.Height, parentViewport.Y))
                    {
                        //
                        // Header straddles the start edge of the viewport
                        //

                        sizeAfterStartViewportEdge = pixelSize.Height - parentViewport.Y;
                        sizeBeforeStartViewportEdge = pixelSize.Height - sizeAfterStartViewportEdge;

                        viewport.Height = Math.Max(viewport.Height - sizeAfterStartViewportEdge, 0);

                        if (cacheUnit == VirtualizationCacheLengthUnit.Pixel)
                        {
                            cacheBeforeSize = Math.Max(cacheBeforeSize - sizeBeforeStartViewportEdge, 0);
                        }
                        else
                        {
                            cacheBeforeSize = Math.Max(cacheBeforeSize - Math.Floor(logicalSize.Height * sizeBeforeStartViewportEdge / pixelSize.Height), 0);
                        }
                    }
                    else
                    {
                        //
                        // Header is completely before the start edge of the viewport. We do not need to
                        // adjust the cacheBefore size in this case because the cacheBefore is populated
                        // bottom up and we cant really be certain that the header will infact lie within the
                        // cacheBefore region.
                        //
                    }
                }
                else
                {
                    //
                    // Viewport is at or before the start of this panel
                    //

                    if (DoubleUtil.GreaterThan(parentViewport.Height, 0))
                    {
                        if (DoubleUtil.GreaterThanOrClose(parentViewport.Height, pixelSize.Height))
                        {
                            //
                            // Header is completely within the viewport
                            //

                            viewport.Height = Math.Max(0, parentViewport.Height - pixelSize.Height);
                        }
                        else
                        {
                            //
                            // Header straddles the end edge of the viewport
                            //

                            sizeBeforeEndViewportEdge = parentViewport.Height;
                            sizeAfterEndViewportEdge = pixelSize.Height - sizeBeforeEndViewportEdge;

                            viewport.Height = 0;

                            if (cacheUnit == VirtualizationCacheLengthUnit.Pixel)
                            {
                                cacheAfterSize = Math.Max(cacheAfterSize - sizeAfterEndViewportEdge, 0);
                            }
                            else
                            {
                                cacheAfterSize = Math.Max(cacheAfterSize - Math.Floor(logicalSize.Height * sizeAfterEndViewportEdge / pixelSize.Height), 0);
                            }
                        }
                    }
                    else
                    {
                        //
                        // Header is completely after the end edge of the viewport
                        //

                        if (cacheUnit == VirtualizationCacheLengthUnit.Pixel)
                        {
                            cacheAfterSize = Math.Max(cacheAfterSize - pixelSize.Height, 0);
                        }
                        else
                        {
                            cacheAfterSize = Math.Max(cacheAfterSize - logicalSize.Height, 0);
                        }
                    }
                }
            }

            cacheLength = new VirtualizationCacheLength(cacheBeforeSize, cacheAfterSize);
        }
Beispiel #25
0
        private bool IsEndOfCache(
            bool isHorizontal,
            double cacheSize,
            VirtualizationCacheLengthUnit cacheUnit,
            Size stackPixelSizeInCache,
            Size stackLogicalSizeInCache)
        {
            if (!MeasureCaches)
            {
                return true;
            }

            Debug.Assert(cacheUnit != VirtualizationCacheLengthUnit.Page, "Page cacheUnit is not expected here.");

            if (cacheUnit == VirtualizationCacheLengthUnit.Item)
            {
                if (isHorizontal)
                {
                    return DoubleUtil.GreaterThanOrClose(stackLogicalSizeInCache.Width, cacheSize);
                }
                else
                {
                    return DoubleUtil.GreaterThanOrClose(stackLogicalSizeInCache.Height, cacheSize);
                }
            }
            else if (cacheUnit == VirtualizationCacheLengthUnit.Pixel)
            {
                if (isHorizontal)
                {
                    return DoubleUtil.GreaterThanOrClose(stackPixelSizeInCache.Width, cacheSize);
                }
                else
                {
                    return DoubleUtil.GreaterThanOrClose(stackPixelSizeInCache.Height, cacheSize);
                }
            }
            return false;
        }
Beispiel #26
0
        /// <summary>
        /// Extends the viewport to include the cacheSizeBeforeViewport and cacheSizeAfterViewport.
        /// </summary>
        private Rect ExtendViewport(
            IHierarchicalVirtualizationAndScrollInfo virtualizationInfoProvider,
            bool isHorizontal,
            Rect viewport,
            VirtualizationCacheLength cacheLength,
            VirtualizationCacheLengthUnit cacheUnit,
            Size stackPixelSizeInCacheBeforeViewport,
            Size stackLogicalSizeInCacheBeforeViewport,
            Size stackPixelSizeInCacheAfterViewport,
            Size stackLogicalSizeInCacheAfterViewport,
            Size stackPixelSize,
            Size stackLogicalSize,
            ref int itemsInExtendedViewportCount)
        {
            Debug.Assert(cacheUnit != VirtualizationCacheLengthUnit.Page, "Page cacheUnit is not expected here.");

            double pixelSize, pixelSizeBeforeViewport, pixelSizeAfterViewport;
            double logicalSize, logicalSizeBeforeViewport, logicalSizeAfterViewport;
            Rect extendedViewport = viewport;

            if (isHorizontal)
            {
                double approxSizeOfLogicalUnit = (DoubleUtil.GreaterThan(_previousStackPixelSizeInViewport.Width, 0.0) && DoubleUtil.GreaterThan(_previousStackLogicalSizeInViewport.Width, 0.0)) ?
                    _previousStackPixelSizeInViewport.Width / _previousStackLogicalSizeInViewport.Width : ScrollViewer._scrollLineDelta;

                pixelSize = stackPixelSize.Width;
                logicalSize = stackLogicalSize.Width;

                if (MeasureCaches)
                {
                    pixelSizeBeforeViewport = stackPixelSizeInCacheBeforeViewport.Width;
                    pixelSizeAfterViewport = stackPixelSizeInCacheAfterViewport.Width;
                    logicalSizeBeforeViewport = stackLogicalSizeInCacheBeforeViewport.Width;
                    logicalSizeAfterViewport = stackLogicalSizeInCacheAfterViewport.Width;
                }
                else
                {
                    pixelSizeBeforeViewport = (cacheUnit == VirtualizationCacheLengthUnit.Item) ? cacheLength.CacheBeforeViewport * approxSizeOfLogicalUnit : cacheLength.CacheBeforeViewport;
                    pixelSizeAfterViewport = (cacheUnit == VirtualizationCacheLengthUnit.Item) ? cacheLength.CacheAfterViewport * approxSizeOfLogicalUnit : cacheLength.CacheAfterViewport;
                    logicalSizeBeforeViewport = (cacheUnit == VirtualizationCacheLengthUnit.Item) ? cacheLength.CacheBeforeViewport : cacheLength.CacheBeforeViewport / approxSizeOfLogicalUnit;
                    logicalSizeAfterViewport = (cacheUnit == VirtualizationCacheLengthUnit.Item) ? cacheLength.CacheAfterViewport : cacheLength.CacheAfterViewport / approxSizeOfLogicalUnit;

                    if (IsPixelBased)
                    {
                        pixelSizeBeforeViewport = Math.Max(pixelSizeBeforeViewport, Math.Abs(_viewport.X - _extendedViewport.X));
                    }
                    else
                    {
                        logicalSizeBeforeViewport = Math.Max(logicalSizeBeforeViewport, Math.Abs(_viewport.X - _extendedViewport.X));
                    }
                }

                if (IsPixelBased)
                {
                    if (!IsScrolling && virtualizationInfoProvider != null &&
                        IsViewportEmpty(isHorizontal, extendedViewport) &&
                        DoubleUtil.GreaterThan(pixelSizeBeforeViewport, 0))
                    {
                        //
                        // If this is a GroupItem or a TreeViewItem that is completely above the viewport,
                        // then the CacheBeforeViewport allways designates the distance of the bottom of
                        // this panel from the top of the extendedViewport. Hence this computation for the offset.
                        //

                        extendedViewport.X = pixelSize - pixelSizeBeforeViewport;
                    }
                    else
                    {
                        extendedViewport.X -= pixelSizeBeforeViewport;
                    }

                    extendedViewport.Width += pixelSizeBeforeViewport + pixelSizeAfterViewport;

                    //
                    // Once again coerce the extended viewport dimensions to be within valid range.
                    //
                    if (IsScrolling)
                    {
                        if (DoubleUtil.LessThan(extendedViewport.X, 0.0))
                        {
                            extendedViewport.Width = Math.Max(extendedViewport.Width + extendedViewport.X, 0.0);
                            extendedViewport.X = 0.0;
                        }

                        if (DoubleUtil.GreaterThan(extendedViewport.X + extendedViewport.Width, _scrollData._extent.Width))
                        {
                            extendedViewport.Width = _scrollData._extent.Width - extendedViewport.X;
                        }
                    }
                }
                else
                {
                    if (!IsScrolling && virtualizationInfoProvider != null &&
                        IsViewportEmpty(isHorizontal, extendedViewport) &&
                        DoubleUtil.GreaterThan(pixelSizeBeforeViewport, 0))
                    {
                        //
                        // If this is a GroupItem or a TreeViewItem that is completely above the viewport,
                        // then the CacheBeforeViewport allways designates the distance of the bottom of
                        // this panel from the top of the extendedViewport. Hence this computation for the offset.
                        //

                        extendedViewport.X = logicalSize - logicalSizeBeforeViewport;
                    }
                    else
                    {
                        extendedViewport.X -= logicalSizeBeforeViewport;
                    }

                    extendedViewport.Width += pixelSizeBeforeViewport + pixelSizeAfterViewport;

                    if (IsScrolling)
                    {
                        if (DoubleUtil.LessThan(extendedViewport.X, 0.0))
                        {
                            extendedViewport.Width = Math.Max(extendedViewport.Width / approxSizeOfLogicalUnit + extendedViewport.X, 0.0) * approxSizeOfLogicalUnit;
                            extendedViewport.X = 0.0;
                        }

                        if (DoubleUtil.GreaterThan(extendedViewport.X + extendedViewport.Width / approxSizeOfLogicalUnit, _scrollData._extent.Width))
                        {
                            extendedViewport.Width = (_scrollData._extent.Width - extendedViewport.X) * approxSizeOfLogicalUnit;
                        }
                    }
                }
            }
            else
            {
                double approxSizeOfLogicalUnit = (DoubleUtil.GreaterThan(_previousStackPixelSizeInViewport.Height, 0.0) && DoubleUtil.GreaterThan(_previousStackLogicalSizeInViewport.Height, 0.0)) ?
                    _previousStackPixelSizeInViewport.Height / _previousStackLogicalSizeInViewport.Height : ScrollViewer._scrollLineDelta;

                pixelSize = stackPixelSize.Height;
                logicalSize = stackLogicalSize.Height;

                if (MeasureCaches)
                {
                    pixelSizeBeforeViewport = stackPixelSizeInCacheBeforeViewport.Height;
                    pixelSizeAfterViewport = stackPixelSizeInCacheAfterViewport.Height;
                    logicalSizeBeforeViewport = stackLogicalSizeInCacheBeforeViewport.Height;
                    logicalSizeAfterViewport = stackLogicalSizeInCacheAfterViewport.Height;
                }
                else
                {
                    pixelSizeBeforeViewport = (cacheUnit == VirtualizationCacheLengthUnit.Item) ? cacheLength.CacheBeforeViewport * approxSizeOfLogicalUnit : cacheLength.CacheBeforeViewport;
                    pixelSizeAfterViewport = (cacheUnit == VirtualizationCacheLengthUnit.Item) ? cacheLength.CacheAfterViewport * approxSizeOfLogicalUnit : cacheLength.CacheAfterViewport;
                    logicalSizeBeforeViewport = (cacheUnit == VirtualizationCacheLengthUnit.Item) ? cacheLength.CacheBeforeViewport : cacheLength.CacheBeforeViewport / approxSizeOfLogicalUnit;
                    logicalSizeAfterViewport = (cacheUnit == VirtualizationCacheLengthUnit.Item) ? cacheLength.CacheAfterViewport : cacheLength.CacheAfterViewport / approxSizeOfLogicalUnit;

                    if (IsPixelBased)
                    {
                        pixelSizeBeforeViewport = Math.Max(pixelSizeBeforeViewport, Math.Abs(_viewport.Y - _extendedViewport.Y));
                    }
                    else
                    {
                        logicalSizeBeforeViewport = Math.Max(logicalSizeBeforeViewport, Math.Abs(_viewport.Y - _extendedViewport.Y));
                    }
                }

                if (IsPixelBased)
                {
                    if (!IsScrolling && virtualizationInfoProvider != null &&
                        IsViewportEmpty(isHorizontal, extendedViewport) &&
                        DoubleUtil.GreaterThan(pixelSizeBeforeViewport, 0))
                    {
                        //
                        // If this is a GroupItem or a TreeViewItem that is completely above the viewport,
                        // then the CacheBeforeViewport allways designates the distance of the bottom of
                        // this panel from the top of the extendedViewport. Hence this computation for the offset.
                        //

                        extendedViewport.Y = pixelSize - pixelSizeBeforeViewport;
                    }
                    else
                    {
                        extendedViewport.Y -= pixelSizeBeforeViewport;
                    }

                    extendedViewport.Height += pixelSizeBeforeViewport + pixelSizeAfterViewport;

                    //
                    // Once again coerce the extended viewport dimensions to be within valid range.
                    //
                    if (IsScrolling)
                    {
                        if (DoubleUtil.LessThan(extendedViewport.Y, 0.0))
                        {
                            extendedViewport.Height = Math.Max(extendedViewport.Height + extendedViewport.Y, 0.0);
                            extendedViewport.Y = 0.0;
                        }

                        if (DoubleUtil.GreaterThan(extendedViewport.Y + extendedViewport.Height, _scrollData._extent.Height))
                        {
                            extendedViewport.Height = _scrollData._extent.Height - extendedViewport.Y;
                        }
                    }
                }
                else
                {
                    if (!IsScrolling && virtualizationInfoProvider != null &&
                        IsViewportEmpty(isHorizontal, extendedViewport) &&
                        DoubleUtil.GreaterThan(pixelSizeBeforeViewport, 0))
                    {
                        //
                        // If this is a GroupItem or a TreeViewItem that is completely above the viewport,
                        // then the CacheBeforeViewport allways designates the distance of the bottom of
                        // this panel from the top of the extendedViewport. Hence this computation for the offset.
                        //

                        extendedViewport.Y = logicalSize - logicalSizeBeforeViewport;
                    }
                    else
                    {
                        extendedViewport.Y -= logicalSizeBeforeViewport;
                    }

                    extendedViewport.Height += pixelSizeBeforeViewport + pixelSizeAfterViewport;

                    if (IsScrolling)
                    {
                        if (DoubleUtil.LessThan(extendedViewport.Y, 0.0))
                        {
                            extendedViewport.Height = Math.Max(extendedViewport.Height / approxSizeOfLogicalUnit + extendedViewport.Y, 0.0) * approxSizeOfLogicalUnit;
                            extendedViewport.Y = 0.0;
                        }

                        if (DoubleUtil.GreaterThan(extendedViewport.Y + extendedViewport.Height / approxSizeOfLogicalUnit, _scrollData._extent.Height))
                        {
                            extendedViewport.Height = (_scrollData._extent.Height - extendedViewport.Y) * approxSizeOfLogicalUnit;
                        }
                    }
                }
            }

            if (MeasureCaches)
            {
                itemsInExtendedViewportCount = _actualItemsInExtendedViewportCount;
            }
            else
            {
                double factor = Math.Max(1.0, isHorizontal ? extendedViewport.Width / viewport.Width : extendedViewport.Height / viewport.Height);
                int calcItemsInExtendedViewportCount = (int)Math.Ceiling(factor * _actualItemsInExtendedViewportCount);
                itemsInExtendedViewportCount = Math.Max(calcItemsInExtendedViewportCount, itemsInExtendedViewportCount);
            }

            return extendedViewport;
        }
 /// <summary>Initializes a new instance of the <see cref="T:System.Windows.Controls.HierarchicalVirtualizationConstraints" /> class.</summary>
 /// <param name="cacheLength">The size of the cache before and after the viewport.</param>
 /// <param name="cacheLengthUnit">The type of unit that is used by the <see cref="P:System.Windows.Controls.HierarchicalVirtualizationConstraints.CacheLength" /> property.</param>
 /// <param name="viewport">The size of the cache before and after the viewport.</param>
 // Token: 0x06005412 RID: 21522 RVA: 0x00174D2F File Offset: 0x00172F2F
 public HierarchicalVirtualizationConstraints(VirtualizationCacheLength cacheLength, VirtualizationCacheLengthUnit cacheLengthUnit, Rect viewport)
 {
     this._cacheLength      = cacheLength;
     this._cacheLengthUnit  = cacheLengthUnit;
     this._viewport         = viewport;
     this._scrollGeneration = 0L;
 }