浏览代码

Pick nearest parent if container query doesn't specify container name (#18707)

* pick nearest parent if container query doesn't specify container name

* add to string overrides for queries
Emmanuel Hansen 5 月之前
父节点
当前提交
6431b765a1

+ 2 - 1
src/Avalonia.Base/Styling/Activators/ContainerQueryActivatorBase.cs

@@ -74,7 +74,8 @@ namespace Avalonia.Styling.Activators
         internal static Layoutable? GetContainer(Visual visual, string? containerName)
         {
             return visual.GetVisualAncestors().Where(x => x is Layoutable layoutable &&
-                (Container.GetName(layoutable) == containerName)).FirstOrDefault() as Layoutable;
+                ((containerName == null && Container.GetSizing(layoutable) != ContainerSizing.Normal)
+                || (containerName != null && Container.GetName(layoutable) == containerName))).FirstOrDefault() as Layoutable;
         }
 
         private void HeightChanged(object? sender, EventArgs e)

+ 26 - 6
src/Avalonia.Base/Styling/ScreenQueries.cs

@@ -67,11 +67,22 @@ namespace Avalonia.Styling
                 SelectorMatch.AlwaysThisInstance : SelectorMatch.NeverThisInstance;
         }
 
-        public override string ToString() => "width";
+        public override string ToString() => ToString(null);
 
         public override string ToString(ContainerQuery? owner)
         {
-            throw new NotImplementedException();
+            var prop = Argument.@operator switch
+            {
+                StyleQueryComparisonOperator.None => "",
+                StyleQueryComparisonOperator.Equals => "width",
+                StyleQueryComparisonOperator.LessThan => "",
+                StyleQueryComparisonOperator.GreaterThan => "",
+                StyleQueryComparisonOperator.LessThanOrEquals => "max-width",
+                StyleQueryComparisonOperator.GreaterThanOrEquals => "min-width",
+                _ => throw new NotImplementedException(),
+            };
+
+            return $"{prop}:{Argument.value}";
         }
     }
 
@@ -112,8 +123,6 @@ namespace Avalonia.Styling
                 return SelectorMatch.NeverThisInstance;
             }
 
-            var isvalueTrue = IsTrue(argument.@operator, argument.value);
-
             bool IsTrue(StyleQueryComparisonOperator comparisonOperator, double value)
             {
                 switch (comparisonOperator)
@@ -139,11 +148,22 @@ namespace Avalonia.Styling
                 SelectorMatch.AlwaysThisInstance : SelectorMatch.NeverThisInstance;
         }
 
-        public override string ToString() => "height";
+        public override string ToString() => ToString(null);
 
         public override string ToString(ContainerQuery? owner)
         {
-            throw new NotImplementedException();
+            var prop = Argument.@operator switch
+            {
+                StyleQueryComparisonOperator.None => "",
+                StyleQueryComparisonOperator.Equals => "height",
+                StyleQueryComparisonOperator.LessThan => "",
+                StyleQueryComparisonOperator.GreaterThan => "",
+                StyleQueryComparisonOperator.LessThanOrEquals => "max-height",
+                StyleQueryComparisonOperator.GreaterThanOrEquals => "min-height",
+                _ => throw new NotImplementedException(),
+            };
+
+            return $"{prop}:{Argument.value}";
         }
     }
 }

+ 22 - 14
tests/Avalonia.Base.UnitTests/Styling/ContainerTests.cs

@@ -30,7 +30,7 @@ namespace Avalonia.Base.UnitTests.Styling
             containerQuery1.Children.Add(new Style(x => x.Is<Border>())
             {
                 Setters = { new Setter(Control.WidthProperty, 200.0) }
-            });            
+            });
             var containerQuery2 = new ContainerQuery(x => new WidthQuery(x, StyleQueryComparisonOperator.GreaterThan, 500));
             containerQuery2.Children.Add(new Style(x => x.Is<Border>())
             {
@@ -43,11 +43,13 @@ namespace Avalonia.Base.UnitTests.Styling
                 Name = "Child",
                 HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Stretch
             };
+            var stack = new StackPanel();
+            stack.Children.Add(child);
             var border = new Border()
             {
                 HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Stretch,
                 VerticalAlignment = Avalonia.Layout.VerticalAlignment.Stretch,
-                Child = child,
+                Child = stack,
                 Name = "Parent"
             };
             Container.SetSizing(border, Avalonia.Styling.ContainerSizing.Width);
@@ -55,13 +57,13 @@ namespace Avalonia.Base.UnitTests.Styling
             root.Child = border;
 
             root.LayoutManager.ExecuteInitialLayoutPass();
-            Assert.Equal(child.Width, 200.0);
+            Assert.Equal(200, child.Width);
 
             root.ClientSize = new Size(600, 600);
             root.InvalidateMeasure();
 
             root.LayoutManager.ExecuteLayoutPass();
-            Assert.Equal(child.Width, 500.0);
+            Assert.Equal(500, child.Width);
         }
 
         [Fact]
@@ -89,11 +91,13 @@ namespace Avalonia.Base.UnitTests.Styling
                 Name = "Child",
                 VerticalAlignment = Avalonia.Layout.VerticalAlignment.Stretch
             };
+            var stack = new StackPanel();
+            stack.Children.Add(child);
             var border = new Border()
             {
                 HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Stretch,
                 VerticalAlignment = Avalonia.Layout.VerticalAlignment.Stretch,
-                Child = child,
+                Child = stack,
                 Name = "Parent"
             };
             Container.SetSizing(border, Avalonia.Styling.ContainerSizing.Height);
@@ -101,13 +105,13 @@ namespace Avalonia.Base.UnitTests.Styling
             root.Child = border;
 
             root.LayoutManager.ExecuteInitialLayoutPass();
-            Assert.Equal(child.Height, 200.0);
+            Assert.Equal(200, child.Height);
 
             root.ClientSize = new Size(600, 600);
             root.InvalidateMeasure();
 
             root.LayoutManager.ExecuteLayoutPass();
-            Assert.Equal(child.Height, 500.0);
+            Assert.Equal(500, child.Height);
         }
 
         [Fact]
@@ -128,8 +132,8 @@ namespace Avalonia.Base.UnitTests.Styling
             {
                 Setters = { new Setter(Control.WidthProperty, 300.0) }
             });
-            root.Styles.Add(containerQuery2);
             root.Styles.Add(containerQuery1);
+            root.Styles.Add(containerQuery2);
             var child = new Border()
             {
                 Name = "Child",
@@ -144,11 +148,13 @@ namespace Avalonia.Base.UnitTests.Styling
             };
             Container.SetSizing(controlInner, Avalonia.Styling.ContainerSizing.Width);
             Container.SetName(controlInner, "TEST");
+            var stack = new StackPanel();
+            stack.Children.Add(controlInner);
             var border = new Border()
             {
                 HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Stretch,
                 VerticalAlignment = Avalonia.Layout.VerticalAlignment.Stretch,
-                Child = controlInner,
+                Child = stack,
                 Name = "Parent"
             };
             Container.SetSizing(border, Avalonia.Styling.ContainerSizing.Width);
@@ -158,7 +164,7 @@ namespace Avalonia.Base.UnitTests.Styling
             root.LayoutManager.ExecuteInitialLayoutPass();
 
             root.LayoutManager.ExecuteLayoutPass();
-            Assert.Equal(child.Width, 300.0);
+            Assert.Equal(300, child.Width);
         }
 
         [Fact]
@@ -174,13 +180,13 @@ namespace Avalonia.Base.UnitTests.Styling
             {
                 Setters = { new Setter(Control.HeightProperty, 200.0) }
             });
-            var containerQuery2 = new ContainerQuery(x => new HeightQuery(x, StyleQueryComparisonOperator.LessThanOrEquals, 500), "TEST");
+            var containerQuery2 = new ContainerQuery(x => new HeightQuery(x, StyleQueryComparisonOperator.LessThanOrEquals, 450), "TEST");
             containerQuery2.Children.Add(new Style(x => x.Is<Border>())
             {
                 Setters = { new Setter(Control.HeightProperty, 300.0) }
             });
-            root.Styles.Add(containerQuery2);
             root.Styles.Add(containerQuery1);
+            root.Styles.Add(containerQuery2);
             var child = new Border()
             {
                 Name = "Child",
@@ -195,11 +201,13 @@ namespace Avalonia.Base.UnitTests.Styling
             };
             Container.SetSizing(controlInner, Avalonia.Styling.ContainerSizing.Height);
             Container.SetName(controlInner, "TEST");
+            var stack = new StackPanel();
+            stack.Children.Add(controlInner);
             var border = new Border()
             {
                 HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Stretch,
                 VerticalAlignment = Avalonia.Layout.VerticalAlignment.Stretch,
-                Child = controlInner,
+                Child = stack,
                 Name = "Parent"
             };
             Container.SetSizing(border, Avalonia.Styling.ContainerSizing.Height);
@@ -209,7 +217,7 @@ namespace Avalonia.Base.UnitTests.Styling
             root.LayoutManager.ExecuteInitialLayoutPass();
 
             root.LayoutManager.ExecuteLayoutPass();
-            Assert.Equal(child.Height, 300.0);
+            Assert.Equal(300, child.Height);
         }
     }
 }