diff --git a/src/Avalonia.Base/Visual.cs b/src/Avalonia.Base/Visual.cs index 8b0cc06136..df0c5b100f 100644 --- a/src/Avalonia.Base/Visual.cs +++ b/src/Avalonia.Base/Visual.cs @@ -732,6 +732,23 @@ namespace Avalonia } } + internal override void OnTemplatedParentControlThemeChanged() + { + base.OnTemplatedParentControlThemeChanged(); + + var count = VisualChildren.Count; + var templatedParent = TemplatedParent; + + for (var i = 0; i < count; ++i) + { + if (VisualChildren[i] is StyledElement child && + child.TemplatedParent == templatedParent) + { + child.OnTemplatedParentControlThemeChanged(); + } + } + } + /// /// Computes the value according to the /// and diff --git a/src/Avalonia.Controls/Primitives/TemplatedControl.cs b/src/Avalonia.Controls/Primitives/TemplatedControl.cs index d8874832bd..8253342782 100644 --- a/src/Avalonia.Controls/Primitives/TemplatedControl.cs +++ b/src/Avalonia.Controls/Primitives/TemplatedControl.cs @@ -405,22 +405,5 @@ namespace Avalonia.Controls.Primitives } } } - - internal override void OnTemplatedParentControlThemeChanged() - { - base.OnTemplatedParentControlThemeChanged(); - - var count = VisualChildren.Count; - var templatedParent = TemplatedParent; - - for (var i = 0; i < count; ++i) - { - if (VisualChildren[i] is TemplatedControl child && - child.TemplatedParent == templatedParent) - { - child.OnTemplatedParentControlThemeChanged(); - } - } - } } } diff --git a/tests/Avalonia.Base.UnitTests/Styling/StyledElementTests_Theming.cs b/tests/Avalonia.Base.UnitTests/Styling/StyledElementTests_Theming.cs index 60603937d9..6ba648af78 100644 --- a/tests/Avalonia.Base.UnitTests/Styling/StyledElementTests_Theming.cs +++ b/tests/Avalonia.Base.UnitTests/Styling/StyledElementTests_Theming.cs @@ -569,6 +569,46 @@ public class StyledElementTests_Theming Assert.Equal(Brushes.Green, border.Background); } + [Fact] + public void TemplatedParent_Theme_Change_Applies_Recursively_To_VisualChildren() + { + var theme = CreateDerivedTheme(); + var target = CreateTarget(); + + Assert.Null(target.Theme); + Assert.Null(target.Template); + + var root = CreateRoot(target, theme.BasedOn); + + Assert.NotNull(target.Theme); + Assert.NotNull(target.Template); + + root.Styles.Add(new Style(x => x.OfType().Class("foo")) + { + Setters = { new Setter(StyledElement.ThemeProperty, theme) } + }); + + root.LayoutManager.ExecuteLayoutPass(); + + var border = Assert.IsType(target.VisualChild); + var inner = Assert.IsType(border.Child); + + Assert.Equal(Brushes.Red, border.Background); + Assert.Equal(Brushes.Red, inner.Background); + + Assert.Equal(null, inner.BorderBrush); + Assert.Equal(null, inner.BorderBrush); + + target.Classes.Add("foo"); + root.LayoutManager.ExecuteLayoutPass(); + + Assert.Equal(Brushes.Green, border.Background); + Assert.Equal(Brushes.Green, inner.Background); + + Assert.Equal(Brushes.Cyan, inner.BorderBrush); + Assert.Equal(Brushes.Cyan, inner.BorderBrush); + } + private static ThemedControl CreateTarget() { return new ThemedControl(); @@ -595,7 +635,8 @@ public class StyledElementTests_Theming private static ControlTheme CreateTheme(string tag = "theme") { - var template = new FuncControlTemplate((o, n) => new Border()); + var template = new FuncControlTemplate( + (o, n) => new Border() { Child = new Border() }); return new ControlTheme {