Browse Source

Set owner on Styles children.

And added some unit tests.
Steven Kirk 5 years ago
parent
commit
d138523b8e

+ 16 - 0
src/Avalonia.Styling/Styling/Styles.cs

@@ -233,6 +233,14 @@ namespace Avalonia.Styling
 
             Owner = owner;
             _resources?.AddOwner(owner);
+
+            foreach (var child in this)
+            {
+                if (child is IResourceProvider r)
+                {
+                    r.AddOwner(owner);
+                }
+            }
         }
 
         /// <inheritdoc/>
@@ -244,6 +252,14 @@ namespace Avalonia.Styling
             {
                 Owner = null;
                 _resources?.RemoveOwner(owner);
+
+                foreach (var child in this)
+                {
+                    if (child is IResourceProvider r)
+                    {
+                        r.RemoveOwner(owner);
+                    }
+                }
             }
         }
 

+ 39 - 0
tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/DynamicResourceExtensionTests.cs

@@ -592,6 +592,45 @@ namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions
             }
         }
 
+        [Fact]
+        public void DynamicResource_Can_Be_Found_In_Nested_Style_File()
+        {
+            var style1Xaml = @"
+<Styles xmlns='https://github.com/avaloniaui'
+       xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
+  <StyleInclude Source='test:style2.xaml'/>
+</Styles>";
+            var style2Xaml = @"
+<Style xmlns='https://github.com/avaloniaui'
+       xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
+  <Style.Resources>
+    <Color x:Key='Red'>Red</Color>
+    <SolidColorBrush x:Key='RedBrush' Color='{DynamicResource Red}'/>
+  </Style.Resources>
+</Style>";
+            using (StyledWindow(
+                ("test:style1.xaml", style1Xaml),
+                ("test:style2.xaml", style2Xaml)))
+            {
+                var xaml = @"
+<Window xmlns='https://github.com/avaloniaui'
+        xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
+    <Window.Styles>
+        <StyleInclude Source='test:style1.xaml'/>
+    </Window.Styles>
+    <Border Name='border' Background='{DynamicResource RedBrush}'/>
+</Window>";
+
+                var loader = new AvaloniaXamlLoader();
+                var window = (Window)loader.Load(xaml);
+                var border = window.FindControl<Border>("border");
+                var borderBrush = (ISolidColorBrush)border.Background;
+
+                Assert.NotNull(borderBrush);
+                Assert.Equal(0xffff0000, borderBrush.Color.ToUint32());
+            }
+        }
+
         [Fact]
         public void Control_Property_Is_Updated_When_Parent_Is_Changed()
         {

+ 29 - 1
tests/Avalonia.Styling.UnitTests/StylesTests.cs

@@ -40,7 +40,7 @@ namespace Avalonia.Styling.UnitTests
         public void Should_Set_Owner_On_Assigned_Resources()
         {
             var host = new Mock<IResourceHost>();
-            var target = new Style();
+            var target = new Styles();
             ((IResourceProvider)target).AddOwner(host.Object);
 
             var resources = new Mock<IResourceDictionary>();
@@ -63,6 +63,34 @@ namespace Avalonia.Styling.UnitTests
             resources.Verify(x => x.AddOwner(host.Object), Times.Once);
         }
 
+        [Fact]
+        public void Should_Set_Owner_On_Child_Style()
+        {
+            var host = new Mock<IResourceHost>();
+            var target = new Styles();
+            ((IResourceProvider)target).AddOwner(host.Object);
+
+            var style = new Mock<IStyle>();
+            var resourceProvider = style.As<IResourceProvider>();
+            target.Add(style.Object);
+
+            resourceProvider.Verify(x => x.AddOwner(host.Object), Times.Once);
+        }
+
+        [Fact]
+        public void Should_Set_Owner_On_Child_Style_2()
+        {
+            var host = new Mock<IResourceHost>();
+            var target = new Styles();
+
+            var style = new Mock<IStyle>();
+            var resourceProvider = style.As<IResourceProvider>();
+            target.Add(style.Object);
+
+            host.ResetCalls();
+            ((IResourceProvider)target).AddOwner(host.Object);
+            resourceProvider.Verify(x => x.AddOwner(host.Object), Times.Once);
+        }
         [Fact]
         public void Finds_Resource_In_Merged_Dictionary()
         {