Browse Source

Fix Window.MeasureOverride measuring with the old ClientSize (#18338)

Julien Lebosquain 8 months ago
parent
commit
b815659435
2 changed files with 24 additions and 5 deletions
  1. 10 5
      src/Avalonia.Controls/Window.cs
  2. 14 0
      tests/Avalonia.Controls.UnitTests/WindowTests.cs

+ 10 - 5
src/Avalonia.Controls/Window.cs

@@ -1057,8 +1057,13 @@ namespace Avalonia.Controls
         {
         {
             var sizeToContent = SizeToContent;
             var sizeToContent = SizeToContent;
             var clientSize = ClientSize;
             var clientSize = ClientSize;
-            var constraint = clientSize;
             var maxAutoSize = PlatformImpl?.MaxAutoSizeHint ?? Size.Infinity;
             var maxAutoSize = PlatformImpl?.MaxAutoSizeHint ?? Size.Infinity;
+            var useAutoWidth = sizeToContent.HasAllFlags(SizeToContent.Width);
+            var useAutoHeight = sizeToContent.HasAllFlags(SizeToContent.Height);
+
+            var constraint = new Size(
+                useAutoWidth || double.IsInfinity(availableSize.Width) ? clientSize.Width : availableSize.Width,
+                useAutoHeight || double.IsInfinity(availableSize.Height) ? clientSize.Height : availableSize.Height);
 
 
             if (MaxWidth > 0 && MaxWidth < maxAutoSize.Width)
             if (MaxWidth > 0 && MaxWidth < maxAutoSize.Width)
             {
             {
@@ -1069,19 +1074,19 @@ namespace Avalonia.Controls
                 maxAutoSize = maxAutoSize.WithHeight(MaxHeight);
                 maxAutoSize = maxAutoSize.WithHeight(MaxHeight);
             }
             }
 
 
-            if (sizeToContent.HasAllFlags(SizeToContent.Width))
+            if (useAutoWidth)
             {
             {
                 constraint = constraint.WithWidth(maxAutoSize.Width);
                 constraint = constraint.WithWidth(maxAutoSize.Width);
             }
             }
 
 
-            if (sizeToContent.HasAllFlags(SizeToContent.Height))
+            if (useAutoHeight)
             {
             {
                 constraint = constraint.WithHeight(maxAutoSize.Height);
                 constraint = constraint.WithHeight(maxAutoSize.Height);
             }
             }
 
 
             var result = base.MeasureOverride(constraint);
             var result = base.MeasureOverride(constraint);
 
 
-            if (!sizeToContent.HasAllFlags(SizeToContent.Width))
+            if (!useAutoWidth)
             {
             {
                 if (!double.IsInfinity(availableSize.Width))
                 if (!double.IsInfinity(availableSize.Width))
                 {
                 {
@@ -1093,7 +1098,7 @@ namespace Avalonia.Controls
                 }
                 }
             }
             }
 
 
-            if (!sizeToContent.HasAllFlags(SizeToContent.Height))
+            if (!useAutoHeight)
             {
             {
                 if (!double.IsInfinity(availableSize.Height))
                 if (!double.IsInfinity(availableSize.Height))
                 {
                 {

+ 14 - 0
tests/Avalonia.Controls.UnitTests/WindowTests.cs

@@ -5,6 +5,7 @@ using Avalonia.Media;
 using Avalonia.Platform;
 using Avalonia.Platform;
 using Avalonia.Rendering;
 using Avalonia.Rendering;
 using Avalonia.Rendering.Composition;
 using Avalonia.Rendering.Composition;
+using Avalonia.Threading;
 using Avalonia.UnitTests;
 using Avalonia.UnitTests;
 using Moq;
 using Moq;
 using Xunit;
 using Xunit;
@@ -686,10 +687,23 @@ namespace Avalonia.Controls.UnitTests
                         Content = child
                         Content = child
                     };
                     };
 
 
+                    // Verify that the child is initially measured with our Width/Height.
                     Show(target);
                     Show(target);
 
 
                     Assert.Equal(1, child.MeasureSizes.Count);
                     Assert.Equal(1, child.MeasureSizes.Count);
                     Assert.Equal(new Size(100, 50), child.MeasureSizes[0]);
                     Assert.Equal(new Size(100, 50), child.MeasureSizes[0]);
+
+                    // Now change the bounds: verify that we are using the new Width/Height, and not the old ClientSize.
+                    child.MeasureSizes.Clear();
+                    child.InvalidateMeasure();
+
+                    target.Width = 120;
+                    target.Height = 70;
+
+                    Dispatcher.UIThread.RunJobs();
+
+                    Assert.Equal(1, child.MeasureSizes.Count);
+                    Assert.Equal(new Size(120, 70), child.MeasureSizes[0]);
                 }
                 }
             }
             }