@@ -27,13 +27,19 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
27
27
/// </remarks>
28
28
public partial class ConstrainedBox : ContentPresenter // TODO: Should be FrameworkElement directly, see https://github.com/microsoft/microsoft-ui-xaml/issues/5530
29
29
{
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 ;
31
32
33
+ private Size _originalSize ;
32
34
private Size _lastMeasuredSize ;
33
35
36
+ private bool IsPositiveRealNumber ( double value ) => ! double . IsNaN ( value ) && ! double . IsInfinity ( value ) && value > 0 ;
37
+
34
38
/// <inheritdoc/>
35
39
protected override Size MeasureOverride ( Size availableSize )
36
40
{
41
+ _originalSize = availableSize ;
42
+
37
43
CalculateConstrainedSize ( ref availableSize ) ;
38
44
39
45
_lastMeasuredSize = availableSize ;
@@ -56,14 +62,23 @@ protected override Size ArrangeOverride(Size finalSize)
56
62
// However, if we always re-calculate even if we are provided the proper finalSize, this can trigger
57
63
// multiple arrange passes and cause a rounding error in layout. Therefore, we only want to
58
64
// 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 )
62
67
{
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 ) ;
64
78
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
+ }
67
82
}
68
83
69
84
return base . ArrangeOverride ( finalSize ) ;
0 commit comments