Beispiel #1
0
        public void Measure(Size availableSize)
        {
            if (PreviousAvailableSize == availableSize || Visibility == Visibility.Collapsed)
            {
                return;
            }
            PreviousAvailableSize = availableSize;

            var  mm = new MinMaxSize(this);
            Size constrainedAvailableSize = Size.MinMax(availableSize - Margin, mm.MinSize, mm.MaxSize);

            Size desiredSize = MeasureOverride(constrainedAvailableSize);

            if (desiredSize.IsInfinite)
            {
                throw new InvalidOperationException($"{nameof(MeasureOverride)} must return a finite size.");
            }

            UnclippedDesiredSize = desiredSize = Size.Max(desiredSize, mm.MinSize);
            DesiredSize          = Size.Min(Size.Min(desiredSize, mm.MaxSize) + Margin, availableSize);
        }
Beispiel #2
0
        public void Arrange(Rect finalRect)
        {
            if (finalRect.IsInfinite)
            {
                throw new ArgumentException($"{nameof(finalRect)} must be finite.", nameof(finalRect));
            }

            if (RenderSlotRect == finalRect || Visibility == Visibility.Collapsed)
            {
                return;
            }
            RenderSlotRect = finalRect;

            Size arrangeSize = Size.Max(RenderSlotRect.Size - Margin, UnclippedDesiredSize);

            if (Align != Align.Stretch)
            {
                arrangeSize.Width = UnclippedDesiredSize.Width;
            }
            if (VerticalAlign != VerticalAlign.Stretch)
            {
                arrangeSize.Height = UnclippedDesiredSize.Height;
            }

            var mm = new MinMaxSize(this);

            arrangeSize = Size.Min(arrangeSize, Size.Max(UnclippedDesiredSize, mm.MaxSize));
            RenderSize  = ArrangeOverride(arrangeSize);

            Size   clippedRenderSize = Size.Min(RenderSize, mm.MaxSize);
            Vector alignOffset       = CalculateAlignOffset(RenderSlotRect.Size - Margin, clippedRenderSize);

            ActualOffset = alignOffset + new Vector(RenderSlotRect.Position) + new Vector(Margin.Left, Margin.Top);

            LayoutClip = new Rect(-alignOffset, RenderSlotRect.Size - Margin)
                         .Intersect(new Rect(new Size(
                                                 mm.MaxSize.IsWidthInfinite ? clippedRenderSize.Width : mm.MaxSize.Width,
                                                 mm.MaxSize.IsHeightInfinite ? clippedRenderSize.Height : mm.MaxSize.Height
                                                 )));
        }
Beispiel #3
0
        public void Measure (Size availableSize)
        {
            if (Visibility == Visibility.Collapsed) {
                UnclippedDesiredSize = Size.Empty;
                DesiredSize = Size.Empty;
                return;
            }

            // Apply margin. availableSize is what parent want us to be.
            Size constrainedAvailableSize = new Size(availableSize.Width - Margin.Width, availableSize.Height - Margin.Height, false);

            // Apply min/max/currentvalue constraints.
            MinMaxSize mm = new MinMaxSize(MinHeight, MaxHeight, MinWidth, MaxWidth, Width, Height);
            constrainedAvailableSize = Size.MinMax(constrainedAvailableSize, mm.MinSize, mm.MaxSize);

            Size desiredSize = MeasureOverride(constrainedAvailableSize);
            if (desiredSize.IsInfinite)
                throw new InvalidOperationException($"{nameof(MeasureOverride)} must return finite size.");

            // Maximize desiredSize with user provided min size.
            desiredSize = Size.Max(desiredSize, mm.MinSize);

            // Here is the "true minimum" desired size - the one that is for sure enough for the control to render its content.
            // UnclippedDesiredSize is needed in ArrangeCore, because due to the layout protocol, arrange should be called
            // with constraints greater or equal to child's desired size returned from MeasureOverride.
            UnclippedDesiredSize = desiredSize;

            // User-specified max size starts to "clip" the control here.
            // Starting from this point desiredSize could be smaller than actually needed to render the whole control.
            desiredSize = Size.Min(desiredSize, mm.MaxSize);

            // Because of negative margins, clipped desired size may be negative.
            // In overconstrained scenario, parent wins and measured size of the child, including any sizes set or computed,
            // cannot be larger than available size. We will clip it later.
            DesiredSize = Size.Min(desiredSize + Margin, availableSize);
        }
Beispiel #4
0
 private Vector CalculateAlignmentOffset ()
 {
     // Clipped RenderSize differs from RenderSize only what MaxWidth/Height explicitly clip the otherwise good arrangement. 
     // For ex, DS<clientSize but DS>MaxWidth - in this case we should initiate clip at MaxWidth and only show Top-Left portion
     // of the element limited by Max properties. It is Top-left because in case when we are clipped by container we also degrade
     // to Top-Left, so we are consistent.
     MinMaxSize mm = new MinMaxSize(MinHeight, MaxHeight, MinWidth, MaxWidth, Width, Height);
     return CalculateAlignmentOffsetCore(CalculateClientSize(), Size.Min(RenderSize, mm.MaxSize));
 }