using System; using Avalonia.Controls; using Avalonia.Controls.Presenters; using Avalonia.Controls.Templates; using Avalonia.Media; using Avalonia.Media.Immutable; using Avalonia.Styling; using Avalonia.UnitTests; using Xunit; namespace Avalonia.Markup.Xaml.UnitTests.Xaml { public class ResourceDictionaryTests : XamlTestBase { [Fact] public void StaticResource_Works_In_ResourceDictionary() { using (StyledWindow()) { var xaml = @" Red "; var resources = (ResourceDictionary)AvaloniaRuntimeXamlLoader.Load(xaml); var brush = (SolidColorBrush)resources["RedBrush"]; Assert.Equal(Colors.Red, brush.Color); } } [Fact] public void DynamicResource_Finds_Resource_In_Parent_Dictionary() { using (StyledWindow()) { var documents = new[] { new RuntimeXamlLoaderDocument(new Uri("avares://Avalonia.Markup.Xaml.UnitTests/dict.xaml"), @" "), new RuntimeXamlLoaderDocument(@" Red "; var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml); var windowResources = (ResourceDictionary)window.Resources; var buttonResources = (ResourceDictionary)((Button)window.Content!).Resources; Assert.True(windowResources.ContainsDeferredKey("Red")); Assert.True(buttonResources.ContainsDeferredKey("Red2")); } } [Fact] public void Item_StaticReferenced_Is_UnDeferred_On_Read() { using (StyledWindow()) { var xaml = @" "; var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml); var windowResources = (ResourceDictionary)window.Resources; var buttonResources = (ResourceDictionary)((Button)window.Content!).Resources; Assert.IsType(buttonResources["Red2"]); Assert.False(windowResources.ContainsDeferredKey("Red")); Assert.False(buttonResources.ContainsDeferredKey("Red2")); } } [Fact] public void Value_Type_With_Parse_Converter_Should_Not_Be_Deferred() { using (StyledWindow()) { var xaml = @" Red "; var resources = (ResourceDictionary)AvaloniaRuntimeXamlLoader.Load(xaml); Assert.False(resources.ContainsDeferredKey("Red")); Assert.IsType(resources["Red"]); } } [Fact] public void Value_Type_With_Ctor_Converter_Should_Not_Be_Deferred() { using (StyledWindow()) { var xaml = @" 1 1 1 1 "; var resources = (ResourceDictionary)AvaloniaRuntimeXamlLoader.Load(xaml); Assert.False(resources.ContainsDeferredKey("Margin")); Assert.IsType(resources["Margin"]); } } [Fact] public void Closest_Resource_Should_Be_Referenced() { using (StyledWindow()) { var xaml = @" "; var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml); var windowResources = (ResourceDictionary)window.Resources; var buttonResources = (ResourceDictionary)((Button)window.Content!).Resources; var brush = Assert.IsType(windowResources["Red2"]); Assert.Equal(Colors.Red, brush.Color); Assert.False(windowResources.ContainsDeferredKey("Red")); Assert.False(windowResources.ContainsDeferredKey("Red2")); Assert.True(buttonResources.ContainsDeferredKey("Red")); } } [Fact] public void Should_Be_Possible_To_Redefine_Referenced_Resource_ControlTheme() { using (StyledWindow()) { var xaml = @" "; var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml); var windowResources = (ResourceDictionary)window.Resources; var innerResources = (ResourceDictionary)((UserControl)window.Content!).Resources; var winButtonTheme = Assert.IsType(windowResources[typeof(Button)]); var innerButtonTheme = Assert.IsType(innerResources[typeof(Button)]); Assert.Equal(winButtonTheme, innerButtonTheme.BasedOn); } } [Fact] public void Should_Be_Possible_To_Redefine_Referenced_Resource() { using (StyledWindow()) { var xaml = @" #aaa "; var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml); var windowResources = (ResourceDictionary)window.Resources; var innerResources = (ResourceDictionary)((UserControl)window.Content!).Resources; var winButtonTheme = Assert.IsType(windowResources["SystemAccentColor"]); var innerButtonTheme = Assert.IsType(innerResources["SystemAccentColor"]); Assert.Equal(winButtonTheme, innerButtonTheme); } } [Fact] public void Dynamically_Changing_Referenced_Resources_Works_With_DynamicResource() { var xaml = @" Red "; var userControl = (UserControl)AvaloniaRuntimeXamlLoader.Load(xaml); Assert.Equal(Colors.Red, ((ISolidColorBrush)userControl.FindResource("brush")!).Color); userControl.Resources.Remove("color"); Assert.Equal(default, ((ISolidColorBrush)userControl.FindResource("brush")!).Color); userControl.Resources.Add("color", Colors.Blue); Assert.Equal(Colors.Blue, ((ISolidColorBrush)userControl.FindResource("brush")!).Color); } [Fact] public void ResourceDictionary_Can_Be_Put_Inside_Of_ResourceDictionary() { using (StyledWindow()) { var xaml = @" "; var resources = (ResourceDictionary)AvaloniaRuntimeXamlLoader.Load(xaml); var nested = (ResourceDictionary)resources["NotAThemeVariantKey"]; Assert.NotNull(nested); } } private IDisposable StyledWindow(params (string, string)[] assets) { var services = TestServices.StyledWindow.With( theme: () => new Styles { WindowStyle(), }); return UnitTestApplication.Start(services); } private Style WindowStyle() { return new Style(x => x.OfType()) { Setters = { new Setter( Window.TemplateProperty, new FuncControlTemplate((x, scope) => new ContentPresenter { Name = "PART_ContentPresenter", [!ContentPresenter.ContentProperty] = x[!Window.ContentProperty], }.RegisterInNameScope(scope))) } }; } } }