protected override Size MeasureOverride(Size availableSize) { arrageRects.Clear(); var requiredSize = new Size(Padding.Left + Padding.Right, Padding.Top + Padding.Bottom); var clientSize = new Size( availableSize.Width - Padding.Left - Padding.Right, availableSize.Height - Padding.Top - Padding.Bottom); if (Children.Count < 1) { return(requiredSize); } if (Orientation == Orientation.Horizontal) { availableRects.MergeItem(new Rect(Padding.Left, Padding.Top, clientSize.Width + HorizontalSpacing, double.PositiveInfinity)); } else { availableRects.MergeItem(new Rect(Padding.Left, Padding.Top, double.PositiveInfinity, clientSize.Height + VerticalSpacing)); } foreach (var child in Children) { child.Measure(clientSize); var childSize = child.DesiredSize; childSize.Width += HorizontalSpacing; childSize.Height += VerticalSpacing; var(index, rect) = Rects.FindEnoughArea(availableRects, childSize); Debug.Assert(index != -1); var(target, clipRight, clipBottom) = rect.Clip(childSize); availableRects.RemoveAt(index); availableRects.CutThenMergeOthers(target, clipRight.GetValueOrDefault(), clipBottom.GetValueOrDefault()); target.Width -= HorizontalSpacing; target.Height -= VerticalSpacing; arrageRects.Add(target); if (Orientation == Orientation.Horizontal) { availableRects.Sort(CompareRectTop); } else { availableRects.Sort(CompareRectLeft); } } availableRects.Clear(); var bounds = arrageRects.GetOutBounds(); requiredSize.Width += bounds.Width; requiredSize.Height += bounds.Height; return(requiredSize); }