@@ -27,13 +27,19 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
2727 /// </remarks>
2828 public partial class ConstrainedBox : ContentPresenter // TODO: Should be FrameworkElement directly, see https://github.com/microsoft/microsoft-ui-xaml/issues/5530
2929 {
30- private bool IsPositiveRealNumber ( double value ) => ! double . IsNaN ( value ) && ! double . IsInfinity ( value ) && value > 0 ;
30+ //// Value used to determine when we re-calculate in the arrange step or re-use a previous calculation. Within roughly a pixel seems like a good value?
31+ private const double CalculationTolerance = 1.5 ;
3132
33+ private Size _originalSize ;
3234 private Size _lastMeasuredSize ;
3335
36+ private bool IsPositiveRealNumber ( double value ) => ! double . IsNaN ( value ) && ! double . IsInfinity ( value ) && value > 0 ;
37+
3438 /// <inheritdoc/>
3539 protected override Size MeasureOverride ( Size availableSize )
3640 {
41+ _originalSize = availableSize ;
42+
3743 CalculateConstrainedSize ( ref availableSize ) ;
3844
3945 _lastMeasuredSize = availableSize ;
@@ -56,14 +62,23 @@ protected override Size ArrangeOverride(Size finalSize)
5662 // However, if we always re-calculate even if we are provided the proper finalSize, this can trigger
5763 // multiple arrange passes and cause a rounding error in layout. Therefore, we only want to
5864 // re-calculate if we think we will have a significant impact.
59- //// TODO: Not sure what good tolerance is here
60- if ( Math . Abs ( finalSize . Width - _lastMeasuredSize . Width ) > 1.5 ||
61- Math . Abs ( finalSize . Height - _lastMeasuredSize . Height ) > 1.5 )
65+ if ( Math . Abs ( finalSize . Width - _lastMeasuredSize . Width ) > CalculationTolerance ||
66+ Math . Abs ( finalSize . Height - _lastMeasuredSize . Height ) > CalculationTolerance )
6267 {
63- CalculateConstrainedSize ( ref finalSize ) ;
68+ // Check if we can re-use our measure calculation if we're given effectively
69+ // the same size as we had in the measure step.
70+ if ( Math . Abs ( finalSize . Width - _originalSize . Width ) <= CalculationTolerance &&
71+ Math . Abs ( finalSize . Height - _originalSize . Height ) <= CalculationTolerance )
72+ {
73+ finalSize = _lastMeasuredSize ;
74+ }
75+ else
76+ {
77+ CalculateConstrainedSize ( ref finalSize ) ;
6478
65- // Copy again so if Arrange is re-triggered we won't re-calculate.
66- _lastMeasuredSize = finalSize ;
79+ // Copy again so if Arrange is re-triggered we won't re-re-calculate.
80+ _lastMeasuredSize = finalSize ;
81+ }
6782 }
6883
6984 return base . ArrangeOverride ( finalSize ) ;
0 commit comments