private void InnerMeasureCore(Size availableSize)
        {
            var(minSize, maxSize) = this.GetMinMax();
            var marginSize = this.GetMarginSize();

            // NaN values are accepted as input here, particularly when coming from
            // SizeThatFits in Image or Scrollviewer. Clamp the value here as it is reused
            // below for the clipping value.
            availableSize = availableSize
                            .NumberOrDefault(MaxSize);

            var frameworkAvailableSize = availableSize
                                         .Subtract(marginSize)
                                         .AtLeastZero()
                                         .AtMost(maxSize);

            var desiredSize = MeasureOverride(frameworkAvailableSize);

            _logDebug?.Trace($"{DepthIndentation}{FormatDebugName()}.MeasureOverride(availableSize={frameworkAvailableSize}): desiredSize={desiredSize} minSize={minSize} maxSize={maxSize} marginSize={marginSize}");

            if (
                double.IsNaN(desiredSize.Width) ||
                double.IsNaN(desiredSize.Height) ||
                double.IsInfinity(desiredSize.Width) ||
                double.IsInfinity(desiredSize.Height)
                )
            {
                throw new InvalidOperationException($"{FormatDebugName()}: Invalid measured size {desiredSize}. NaN or Infinity are invalid desired size.");
            }

            desiredSize = desiredSize
                          .AtLeast(minSize)
                          .AtLeastZero();

            _unclippedDesiredSize = desiredSize;

            var clippedDesiredSize = desiredSize
                                     .Add(marginSize)
                                     // Making sure after adding margins that clipped DesiredSize is not bigger than the AvailableSize
                                     .AtMost(availableSize)
                                     // Margin may be negative
                                     .AtLeastZero();

            // DesiredSize must include margins
            LayoutInformation.SetDesiredSize(this, clippedDesiredSize);

            _logDebug?.Debug($"{DepthIndentation}[{FormatDebugName()}] Measure({Name}/{availableSize}/{Margin}) = {clippedDesiredSize} _unclippedDesiredSize={_unclippedDesiredSize}");
        }
Esempio n. 2
0
        partial void OnMeasurePartial(Size slotSize)
        {
            MeasureCallCount++;
            AvailableMeasureSize = slotSize;

            if (DesiredSizeSelector != null)
            {
                var desiredSize = DesiredSizeSelector(slotSize);

                LayoutInformation.SetDesiredSize(this, desiredSize);
                RequestedDesiredSize = desiredSize;
            }
            else if (RequestedDesiredSize != null)
            {
                var desiredSize = RequestedDesiredSize.Value;

                LayoutInformation.SetDesiredSize(this, desiredSize);
            }
        }
Esempio n. 3
0
        public void When_UpdateLayout_Then_TreeNotMeasuredUsingCachedValue()
        {
            if (Window.Current.RootElement is Panel root)
            {
                var sut = new Grid
                {
                    HorizontalAlignment = HorizontalAlignment.Stretch,
                    VerticalAlignment   = VerticalAlignment.Stretch
                };

                var originalRootAvailableSize = LayoutInformation.GetAvailableSize(root);
                var originalRootDesiredSize   = LayoutInformation.GetDesiredSize(root);
                var originalRootLayoutSlot    = LayoutInformation.GetLayoutSlot(root);

                Size availableSize;
                Rect layoutSlot;
                try
                {
                    LayoutInformation.SetAvailableSize(root, default);
                    LayoutInformation.SetDesiredSize(root, default);
                    LayoutInformation.SetLayoutSlot(root, default);

                    root.Children.Add(sut);
                    sut.UpdateLayout();

                    availableSize = LayoutInformation.GetAvailableSize(sut);
                    layoutSlot    = LayoutInformation.GetLayoutSlot(sut);
                }
                finally
                {
                    LayoutInformation.SetAvailableSize(root, originalRootAvailableSize);
                    LayoutInformation.SetDesiredSize(root, originalRootDesiredSize);
                    LayoutInformation.SetLayoutSlot(root, originalRootLayoutSlot);

                    root.Children.Remove(sut);
                    try { root.UpdateLayout(); }
                    catch { }                     // Make sure to restore visual tree if test has failed!
                }

                Assert.AreNotEqual(default, availableSize);