diff --git a/samples/ControlCatalog/Pages/ThemePage.axaml b/samples/ControlCatalog/Pages/ThemePage.axaml
index 7286b1a46d5..8cb702a77df 100644
--- a/samples/ControlCatalog/Pages/ThemePage.axaml
+++ b/samples/ControlCatalog/Pages/ThemePage.axaml
@@ -54,7 +54,7 @@
-
+
-
+
diff --git a/samples/ControlCatalog/Pages/ThemePage.axaml.cs b/samples/ControlCatalog/Pages/ThemePage.axaml.cs
index 375b5de7406..6b6787113bb 100644
--- a/samples/ControlCatalog/Pages/ThemePage.axaml.cs
+++ b/samples/ControlCatalog/Pages/ThemePage.axaml.cs
@@ -1,6 +1,7 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
+using Avalonia.Styling;
namespace ControlCatalog.Pages
{
@@ -13,7 +14,7 @@ public ThemePage()
AvaloniaXamlLoader.Load(this);
var selector = this.FindControl("Selector")!;
- var themeControl = this.FindControl("ThemeControl")!;
+ var themeVariantScope = this.FindControl("ThemeVariantScope")!;
selector.Items = new[]
{
@@ -29,11 +30,11 @@ public ThemePage()
var theme = (ThemeVariant)selector.SelectedItem!;
if ((string)theme.Key == "Default")
{
- themeControl.ClearValue(ThemeControl.ThemeVariantProperty);
+ themeVariantScope.ClearValue(ThemeVariantProperty);
}
else
{
- themeControl.ThemeVariant = theme;
+ themeVariantScope.ThemeVariant = theme;
}
};
}
diff --git a/src/Avalonia.Base/Controls/IResourceDictionary.cs b/src/Avalonia.Base/Controls/IResourceDictionary.cs
index e3c1a3f9943..2bd1f65638e 100644
--- a/src/Avalonia.Base/Controls/IResourceDictionary.cs
+++ b/src/Avalonia.Base/Controls/IResourceDictionary.cs
@@ -1,4 +1,5 @@
using System.Collections.Generic;
+using Avalonia.Styling;
#nullable enable
diff --git a/src/Avalonia.Base/Controls/IResourceNode.cs b/src/Avalonia.Base/Controls/IResourceNode.cs
index c762590a0cb..d2fa3c7af3d 100644
--- a/src/Avalonia.Base/Controls/IResourceNode.cs
+++ b/src/Avalonia.Base/Controls/IResourceNode.cs
@@ -1,4 +1,5 @@
using Avalonia.Metadata;
+using Avalonia.Styling;
namespace Avalonia.Controls
{
diff --git a/src/Avalonia.Base/Controls/ResourceDictionary.cs b/src/Avalonia.Base/Controls/ResourceDictionary.cs
index 91f15a2a94c..a003fd4ed38 100644
--- a/src/Avalonia.Base/Controls/ResourceDictionary.cs
+++ b/src/Avalonia.Base/Controls/ResourceDictionary.cs
@@ -5,6 +5,7 @@
using System.Linq;
using Avalonia.Collections;
using Avalonia.Controls.Templates;
+using Avalonia.Styling;
namespace Avalonia.Controls
{
diff --git a/src/Avalonia.Base/Controls/ResourceNodeExtensions.cs b/src/Avalonia.Base/Controls/ResourceNodeExtensions.cs
index e8e0dedef40..6e7f64763ec 100644
--- a/src/Avalonia.Base/Controls/ResourceNodeExtensions.cs
+++ b/src/Avalonia.Base/Controls/ResourceNodeExtensions.cs
@@ -1,5 +1,6 @@
using System;
using Avalonia.Reactive;
+using Avalonia.Styling;
#nullable enable
@@ -38,9 +39,7 @@ public static bool TryFindResource(this IResourceHost control, object key, out o
control = control ?? throw new ArgumentNullException(nameof(control));
key = key ?? throw new ArgumentNullException(nameof(key));
- var theme = AvaloniaLocator.Current.GetService()?.ThemeVariant;
-
- return control.TryFindResource(key, theme, out value);
+ return control.TryFindResource(key, null, out value);
}
///
@@ -98,9 +97,7 @@ public static bool TryGetResource(this IResourceHost control, object key, out ob
control = control ?? throw new ArgumentNullException(nameof(control));
key = key ?? throw new ArgumentNullException(nameof(key));
- var theme = AvaloniaLocator.Current.GetService()?.ThemeVariant;
-
- return control.TryGetResource(key, theme, out value);
+ return control.TryGetResource(key, null, out value);
}
public static IObservable");
+ var border = (Border)themeVariantScope.Child!;
Assert.Equal(Colors.White, ((ISolidColorBrush)border.Background)!.Color);
- themeControl.ThemeVariant = ThemeVariant.Dark;
+ themeVariantScope.ThemeVariant = ThemeVariant.Dark;
Assert.Equal(Colors.Black, ((ISolidColorBrush)border.Background)!.Color);
}
@@ -43,7 +44,7 @@ public void DynamicResource_Updated_When_Control_Theme_Changed()
[Fact]
public void DynamicResource_Updated_When_Control_Theme_Changed_No_Xaml()
{
- var themeControl = new ThemeControl
+ var themeVariantScope = new ThemeVariantScope
{
ThemeVariant = ThemeVariant.Light,
Resources = new ResourceDictionary
@@ -56,14 +57,14 @@ public void DynamicResource_Updated_When_Control_Theme_Changed_No_Xaml()
},
Child = new Border()
};
- var border = (Border)themeControl.Child!;
+ var border = (Border)themeVariantScope.Child!;
border[!Border.BackgroundProperty] = new DynamicResourceExtension("DemoBackground");
DelayedBinding.ApplyBindings(border);
Assert.Equal(Colors.White, ((ISolidColorBrush)border.Background)!.Color);
- themeControl.ThemeVariant = ThemeVariant.Dark;
+ themeVariantScope.ThemeVariant = ThemeVariant.Dark;
Assert.Equal(Colors.Black, ((ISolidColorBrush)border.Background)!.Color);
}
@@ -71,11 +72,11 @@ public void DynamicResource_Updated_When_Control_Theme_Changed_No_Xaml()
[Fact]
public void Intermediate_DynamicResource_Updated_When_Control_Theme_Changed()
{
- var themeControl = (ThemeControl)AvaloniaRuntimeXamlLoader.Load(@"
-
-
+
@@ -87,15 +88,15 @@ public void Intermediate_DynamicResource_Updated_When_Control_Theme_Changed()
-
+
-");
- var border = (Border)themeControl.Child!;
+");
+ var border = (Border)themeVariantScope.Child!;
Assert.Equal(Colors.White, ((ISolidColorBrush)border.Background)!.Color);
- themeControl.ThemeVariant = ThemeVariant.Dark;
+ themeVariantScope.ThemeVariant = ThemeVariant.Dark;
Assert.Equal(Colors.Black, ((ISolidColorBrush)border.Background)!.Color);
}
@@ -103,11 +104,11 @@ public void Intermediate_DynamicResource_Updated_When_Control_Theme_Changed()
[Fact]
public void Intermediate_StaticResource_Can_Be_Reached_From_ThemeDictionaries()
{
- var themeControl = (ThemeControl)AvaloniaRuntimeXamlLoader.Load(@"
-
-
+
@@ -120,15 +121,15 @@ public void Intermediate_StaticResource_Can_Be_Reached_From_ThemeDictionaries()
-
+
-");
- var border = (Border)themeControl.Child!;
+");
+ var border = (Border)themeVariantScope.Child!;
Assert.Equal(Colors.White, ((ISolidColorBrush)border.Background)!.Color);
- themeControl.ThemeVariant = ThemeVariant.Dark;
+ themeVariantScope.ThemeVariant = ThemeVariant.Dark;
Assert.Equal(Colors.Black, ((ISolidColorBrush)border.Background)!.Color);
}
@@ -136,11 +137,11 @@ public void Intermediate_StaticResource_Can_Be_Reached_From_ThemeDictionaries()
[Fact]
public void StaticResource_Inside_Of_ThemeDictionaries_Should_Use_Same_Theme_Key()
{
- var themeControl = (ThemeControl)AvaloniaRuntimeXamlLoader.Load(@"
-
-
+
@@ -151,7 +152,7 @@ public void StaticResource_Inside_Of_ThemeDictionaries_Should_Use_Same_Theme_Key
-
+
@@ -167,58 +168,30 @@ public void StaticResource_Inside_Of_ThemeDictionaries_Should_Use_Same_Theme_Key
-");
- var border = (Border)themeControl.Child!;
+");
+ var border = (Border)themeVariantScope.Child!;
Assert.Equal(Colors.White, ((ISolidColorBrush)border.Background)!.Color);
- themeControl.ThemeVariant = ThemeVariant.Dark;
+ themeVariantScope.ThemeVariant = ThemeVariant.Dark;
Assert.Equal(Colors.Black, ((ISolidColorBrush)border.Background)!.Color);
}
- [Fact]
- public void StaticResource_Outside_Of_ThemeDictionaries_Should_Use_Application_ThemeVariant()
- {
- using (AvaloniaLocator.EnterScope())
- {
- var applicationThemeHost = new Mock();
- applicationThemeHost.SetupGet(h => h.ThemeVariant).Returns(ThemeVariant.Dark);
- AvaloniaLocator.CurrentMutable.Bind().ToConstant(applicationThemeHost.Object);
-
- var dictionary = (ResourceDictionary)AvaloniaRuntimeXamlLoader.Load(@"
-
-
-
- Blue
-
-
- Red
-
-
-
-");
-
- var brush = Assert.IsType(dictionary["Brush"]);
- Assert.Equal(Colors.Red, brush.Color);
- }
- }
-
[Fact]
public void StaticResource_Outside_Of_Dictionaries_Should_Use_Control_ThemeVariant()
{
using (AvaloniaLocator.EnterScope())
{
- var applicationThemeHost = new Mock();
+ var applicationThemeHost = new Mock();
applicationThemeHost.SetupGet(h => h.ThemeVariant).Returns(ThemeVariant.Dark);
- AvaloniaLocator.CurrentMutable.Bind().ToConstant(applicationThemeHost.Object);
+ AvaloniaLocator.CurrentMutable.Bind().ToConstant(applicationThemeHost.Object);
- var themeControl = (ThemeControl)AvaloniaRuntimeXamlLoader.Load(@"
-
-
+
@@ -229,13 +202,13 @@ public void StaticResource_Outside_Of_Dictionaries_Should_Use_Control_ThemeVaria
-
+
-");
- var border = (Border)themeControl.Child!;
+");
+ var border = (Border)themeVariantScope.Child!;
- themeControl.ThemeVariant = ThemeVariant.Light;
+ themeVariantScope.ThemeVariant = ThemeVariant.Light;
Assert.Equal(Colors.White, ((ISolidColorBrush)border.Background)!.Color);
}
}
@@ -243,8 +216,8 @@ public void StaticResource_Outside_Of_Dictionaries_Should_Use_Control_ThemeVaria
[Fact]
public void Inner_ThemeDictionaries_Works_Properly()
{
- var themeControl = (ThemeControl)AvaloniaRuntimeXamlLoader.Load(@"
-
@@ -261,12 +234,12 @@ public void Inner_ThemeDictionaries_Works_Properly()
-");
- var border = (Border)themeControl.Child!;
+");
+ var border = (Border)themeVariantScope.Child!;
Assert.Equal(Colors.White, ((ISolidColorBrush)border.Background)!.Color);
- themeControl.ThemeVariant = ThemeVariant.Dark;
+ themeVariantScope.ThemeVariant = ThemeVariant.Dark;
Assert.Equal(Colors.Black, ((ISolidColorBrush)border.Background)!.Color);
}
@@ -274,11 +247,11 @@ public void Inner_ThemeDictionaries_Works_Properly()
[Fact]
public void Inner_Resource_Can_Reference_Parent_ThemeDictionaries()
{
- var themeControl = (ThemeControl)AvaloniaRuntimeXamlLoader.Load(@"
-
-
+
@@ -289,7 +262,7 @@ public void Inner_Resource_Can_Reference_Parent_ThemeDictionaries()
-
+
@@ -298,12 +271,12 @@ public void Inner_Resource_Can_Reference_Parent_ThemeDictionaries()
-");
- var border = (Border)themeControl.Child!;
+");
+ var border = (Border)themeVariantScope.Child!;
Assert.Equal(Colors.White, ((ISolidColorBrush)border.Background)!.Color);
- themeControl.ThemeVariant = ThemeVariant.Dark;
+ themeVariantScope.ThemeVariant = ThemeVariant.Dark;
Assert.Equal(Colors.Black, ((ISolidColorBrush)border.Background)!.Color);
}
@@ -311,11 +284,11 @@ public void Inner_Resource_Can_Reference_Parent_ThemeDictionaries()
[Fact]
public void DynamicResource_Can_Access_Resources_Outside_Of_ThemeDictionaries()
{
- var themeControl = (ThemeControl)AvaloniaRuntimeXamlLoader.Load(@"
-
-
+
@@ -328,15 +301,15 @@ public void DynamicResource_Can_Access_Resources_Outside_Of_ThemeDictionaries()
Black
White
-
+
-");
- var border = (Border)themeControl.Child!;
+");
+ var border = (Border)themeVariantScope.Child!;
Assert.Equal(Colors.White, ((ISolidColorBrush)border.Background)!.Color);
- themeControl.ThemeVariant = ThemeVariant.Dark;
+ themeVariantScope.ThemeVariant = ThemeVariant.Dark;
Assert.Equal(Colors.Black, ((ISolidColorBrush)border.Background)!.Color);
}
@@ -346,16 +319,16 @@ public void Inner_Dictionary_Does_Not_Affect_Parent_Resources()
{
// It might be a nice feature, but neither Avalonia nor UWP supports it.
// Better to expect this limitation with a unit test.
- var themeControl = (ThemeControl)AvaloniaRuntimeXamlLoader.Load(@"
-
-
+
Red
-
+
@@ -371,12 +344,12 @@ public void Inner_Dictionary_Does_Not_Affect_Parent_Resources()
-");
- var border = (Border)themeControl.Child!;
+");
+ var border = (Border)themeVariantScope.Child!;
Assert.Equal(Colors.Red, ((ISolidColorBrush)border.Background)!.Color);
- themeControl.ThemeVariant = ThemeVariant.Dark;
+ themeVariantScope.ThemeVariant = ThemeVariant.Dark;
Assert.Equal(Colors.Red, ((ISolidColorBrush)border.Background)!.Color);
}
@@ -384,11 +357,11 @@ public void Inner_Dictionary_Does_Not_Affect_Parent_Resources()
[Fact]
public void Custom_Theme_Can_Be_Defined_In_ThemeDictionaries()
{
- var themeControl = (ThemeControl)AvaloniaRuntimeXamlLoader.Load(@"
-
-
+
@@ -402,42 +375,69 @@ public void Custom_Theme_Can_Be_Defined_In_ThemeDictionaries()
-
+
-");
- var border = (Border)themeControl.Child!;
+");
+ var border = (Border)themeVariantScope.Child!;
- themeControl.ThemeVariant = new ThemeVariant("Custom");
+ themeVariantScope.ThemeVariant = new ThemeVariant("Custom");
Assert.Equal(Colors.Pink, ((ISolidColorBrush)border.Background)!.Color);
}
[Fact]
- public void Custom_Theme_Fallbacks_To_Inherit_Theme()
+ public void Custom_Theme_Fallbacks_To_Inherit_Theme_DynamicResource()
{
- var themeControl = (ThemeControl)AvaloniaRuntimeXamlLoader.Load(@"
-
-
-
+
+
Black
-
- White
+
+
+
+
+");
+ var border = (Border)themeVariantScope.Child!;
+
+ themeVariantScope.ThemeVariant = new ThemeVariant("Custom", ThemeVariant.Dark);
+
+ Assert.Equal(Colors.Black, ((ISolidColorBrush)border.Background)!.Color);
+ }
+
+ [Fact]
+ public void Custom_Theme_Fallbacks_To_Inherit_Theme_StaticResource()
+ {
+ var themeVariantScope = (ThemeVariantScope)AvaloniaRuntimeXamlLoader.Load(@"
+
+
+
+
+ Custom
+ Dark
+
+
+
+
+
+
+
+ Black
-
+
-
-");
- var border = (Border)themeControl.Child!;
-
- themeControl.ThemeVariant = new ThemeVariant("Custom", ThemeVariant.Dark);
+
+");
+ var border = (Border)themeVariantScope.Child!;
Assert.Equal(Colors.Black, ((ISolidColorBrush)border.Background)!.Color);
}
diff --git a/tests/Avalonia.UnitTests/UnitTestApplication.cs b/tests/Avalonia.UnitTests/UnitTestApplication.cs
index 319aa2fc7c5..b4fe0b6b554 100644
--- a/tests/Avalonia.UnitTests/UnitTestApplication.cs
+++ b/tests/Avalonia.UnitTests/UnitTestApplication.cs
@@ -57,7 +57,7 @@ public override void RegisterServices()
.Bind().ToConstant(Services.FocusManager)
.Bind().ToConstant(Services.GlobalClock)
.BindToSelf(this)
- .BindToSelf(this)
+ .BindToSelf(this)
.Bind().ToConstant(Services.InputManager)
.Bind().ToConstant(Services.KeyboardDevice?.Invoke())
.Bind().ToConstant(Services.KeyboardNavigation)