From 421546609a68933dee4e427968a74733f929fe04 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Wed, 22 Jun 2022 16:13:43 +0200 Subject: [PATCH] Add test/fix for promoted themes. A bit of an edge case here, but we should deal with it. --- src/Avalonia.Base/StyledElement.cs | 4 ++ .../Styling/StyledElementTests_Theming.cs | 41 +++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/src/Avalonia.Base/StyledElement.cs b/src/Avalonia.Base/StyledElement.cs index f377eb848c..189d73c502 100644 --- a/src/Avalonia.Base/StyledElement.cs +++ b/src/Avalonia.Base/StyledElement.cs @@ -652,6 +652,10 @@ namespace Avalonia Theme = change.GetNewValue(); _hasPromotedTheme = true; } + else if (_hasPromotedTheme && change.Priority == BindingPriority.LocalValue) + { + _hasPromotedTheme = false; + } InvalidateStyles(); } diff --git a/tests/Avalonia.Base.UnitTests/Styling/StyledElementTests_Theming.cs b/tests/Avalonia.Base.UnitTests/Styling/StyledElementTests_Theming.cs index c2692c30ab..9b133035f4 100644 --- a/tests/Avalonia.Base.UnitTests/Styling/StyledElementTests_Theming.cs +++ b/tests/Avalonia.Base.UnitTests/Styling/StyledElementTests_Theming.cs @@ -257,6 +257,47 @@ public class StyledElementTests_Theming Assert.Null(target.Template); } + [Fact] + public void Theme_Can_Be_Set_To_LocalValue_While_Updating_Due_To_Style_Class() + { + using var app = UnitTestApplication.Start(TestServices.RealStyler); + var target = CreateTarget(); + var theme1 = CreateTheme(); + var theme2 = new ControlTheme(typeof(ThemedControl)); + var theme3 = new ControlTheme(typeof(ThemedControl)); + var root = new TestRoot() + { + Styles = + { + new Style(x => x.OfType()) + { + Setters = { new Setter(StyledElement.ThemeProperty, theme1) } + }, + new Style(x => x.OfType().Class("bar")) + { + Setters = { new Setter(StyledElement.ThemeProperty, theme2) } + }, + } + }; + + root.Child = target; + root.LayoutManager.ExecuteInitialLayoutPass(); + + Assert.Same(theme1, target.Theme); + Assert.NotNull(target.Template); + + target.Classes.Add("bar"); + + // At this point, theme2 has been promoted to a local value internally in StyledElement; + // make sure that setting a new local value here doesn't cause it to be cleared when we + // do a layout pass because StyledElement thinks its clearing the promoted theme. + target.Theme = theme3; + + root.LayoutManager.ExecuteLayoutPass(); + + Assert.Same(target.Theme, theme3); + } + private static ThemedControl CreateTarget() { return new ThemedControl();