diff --git a/src/CommunityToolkit.Maui.UnitTests/Extensions/AppThemeResourceExtensionTests.cs b/src/CommunityToolkit.Maui.UnitTests/Extensions/AppThemeResourceExtensionTests.cs new file mode 100644 index 0000000000..e725d69960 --- /dev/null +++ b/src/CommunityToolkit.Maui.UnitTests/Extensions/AppThemeResourceExtensionTests.cs @@ -0,0 +1,29 @@ +using CommunityToolkit.Maui.UnitTests.Mocks; +using CommunityToolkit.Maui.UnitTests.Resources.Styles; +using Xunit; + +namespace CommunityToolkit.Maui.UnitTests.Extensions; + +public class AppThemeResourceExtensionTests : BaseViewTest +{ + [Fact] + public async Task SetPropertyViaAppThemeResource() + { + // Arrange + MockApplication application = (MockApplication)ServiceProvider.GetRequiredService(); + bool foundResource; + + // Act + try + { + application.Resources.MergedDictionaries.Add(new AppThemeResourceDictionary()); + foundResource = true; + } + catch (Exception) + { + foundResource = false; + } + // Assert + Assert.True(foundResource, "Failed to load key from AppThemeResourceDictionary. Bug 2761."); + } +} \ No newline at end of file diff --git a/src/CommunityToolkit.Maui.UnitTests/Resources/Styles/AppThemeResourceDictionary.xaml b/src/CommunityToolkit.Maui.UnitTests/Resources/Styles/AppThemeResourceDictionary.xaml new file mode 100644 index 0000000000..504b5f04f8 --- /dev/null +++ b/src/CommunityToolkit.Maui.UnitTests/Resources/Styles/AppThemeResourceDictionary.xaml @@ -0,0 +1,15 @@ + + + + + + + + + \ No newline at end of file diff --git a/src/CommunityToolkit.Maui.UnitTests/Resources/Styles/AppThemeResourceDictionary.xaml.cs b/src/CommunityToolkit.Maui.UnitTests/Resources/Styles/AppThemeResourceDictionary.xaml.cs new file mode 100644 index 0000000000..5a21f7eaa4 --- /dev/null +++ b/src/CommunityToolkit.Maui.UnitTests/Resources/Styles/AppThemeResourceDictionary.xaml.cs @@ -0,0 +1,9 @@ +namespace CommunityToolkit.Maui.UnitTests.Resources.Styles; + +public partial class AppThemeResourceDictionary : ResourceDictionary +{ + public AppThemeResourceDictionary() + { + InitializeComponent(); + } +} \ No newline at end of file diff --git a/src/CommunityToolkit.Maui/Extensions/AppThemeResourceExtension.shared.cs b/src/CommunityToolkit.Maui/Extensions/AppThemeResourceExtension.shared.cs index dfd16a834c..de05ef1218 100644 --- a/src/CommunityToolkit.Maui/Extensions/AppThemeResourceExtension.shared.cs +++ b/src/CommunityToolkit.Maui/Extensions/AppThemeResourceExtension.shared.cs @@ -48,22 +48,32 @@ public BindingBase ProvideValue(IServiceProvider serviceProvider) } } - // Fallback to root object ResourceDictionary (e.g. page-level resources) + // Fallback to root object ResourceDictionary (e.g. page-level or application-level resources) var rootProvider = serviceProvider.GetService(typeof(IRootObjectProvider)) as IRootObjectProvider; var root = rootProvider?.RootObject; - if (root is IResourcesProvider { IsResourcesCreated: true } rootResources - && rootResources.Resources.TryGetValue(Key, out resource)) + + switch (root) { - switch (resource) - { - case AppThemeColor rootColor: - return rootColor.GetBinding(); - case AppThemeObject rootTheme: - return rootTheme.GetBinding(); - default: - var info = (serviceProvider.GetService(typeof(IXmlLineInfoProvider)) as IXmlLineInfoProvider)?.XmlLineInfo; - throw new XamlParseException($"Resource found for key {Key} is not a valid AppTheme resource.", info); - } + case IResourcesProvider { IsResourcesCreated: true } rootResources1 when rootResources1.Resources.TryGetValue(Key, out resource): + // page level? + switch (resource) + { + case AppThemeColor rootColor: + return rootColor.GetBinding(); + case AppThemeObject rootTheme: + return rootTheme.GetBinding(); + } + break; + case ResourceDictionary rootDictionary1 when rootDictionary1.TryGetValue(Key, out resource): + // application level? + switch (resource) + { + case AppThemeColor rootColor: + return rootColor.GetBinding(); + case AppThemeObject rootTheme: + return rootTheme.GetBinding(); + } + break; } if (Application.Current?.Resources.TryGetValueAndSource(Key, out resource, out _) is true)