diff --git a/src/CommunityToolkit.Maui/Extensions/AppThemeResourceExtension.shared.cs b/src/CommunityToolkit.Maui/Extensions/AppThemeResourceExtension.shared.cs
index f96cbe622..0180e2112 100644
--- a/src/CommunityToolkit.Maui/Extensions/AppThemeResourceExtension.shared.cs
+++ b/src/CommunityToolkit.Maui/Extensions/AppThemeResourceExtension.shared.cs
@@ -3,7 +3,7 @@
///
/// A XAML markup extension that enables using and from XAML.
///
-[ContentProperty(nameof(Key)), RequireService([typeof(IServiceProvider), typeof(IProvideParentValues)])]
+[ContentProperty(nameof(Key)), RequireService([typeof(IServiceProvider), typeof(IProvideValueTarget), typeof(IRootObjectProvider)])]
public sealed class AppThemeResourceExtension : IMarkupExtension
{
///
@@ -21,68 +21,106 @@ public BindingBase ProvideValue(IServiceProvider serviceProvider)
if (Key is null)
{
- throw new XamlParseException($"{nameof(AppThemeResourceExtension)}.{nameof(Key)} Cannot be null. You must set a {nameof(Key)} that specifies the AppTheme resource to use", serviceProvider);
+ throw new XamlParseException($"{nameof(AppThemeResourceExtension)}.{nameof(Key)} cannot be null.", serviceProvider);
}
- if (serviceProvider.GetService(typeof(IProvideValueTarget)) is not IProvideParentValues valueProvider)
+ var valueTarget = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;
+ var targetObject = valueTarget?.TargetObject;
+ if (targetObject is null)
{
- throw new ArgumentException(null, nameof(serviceProvider));
+ var info = (serviceProvider.GetService(typeof(IXmlLineInfoProvider)) as IXmlLineInfoProvider)?.XmlLineInfo;
+ throw new XamlParseException($"Cannot determine target for {nameof(AppThemeResourceExtension)}.", info);
}
- if (!TryGetResource(Key, valueProvider.ParentObjects, out var resource, out var resourceDictionary)
- && !TryGetApplicationLevelResource(Key, out resource, out resourceDictionary))
+ if (TryFindResourceInVisualElement(targetObject, Key, out var resource))
{
- var xmlLineInfo = serviceProvider.GetService(typeof(IXmlLineInfoProvider)) is IXmlLineInfoProvider xmlLineInfoProvider ? xmlLineInfoProvider.XmlLineInfo : null;
- throw new XamlParseException($"Resource not found for key {Key}", xmlLineInfo);
+ if (resource is AppThemeColor color)
+ {
+ return color.GetBinding();
+ }
+ if (resource is AppThemeObject theme)
+ {
+ return theme.GetBinding();
+ }
+
+ var info = (serviceProvider.GetService(typeof(IXmlLineInfoProvider)) as IXmlLineInfoProvider)?.XmlLineInfo;
+ throw new XamlParseException($"Resource found for key {Key} is not a valid AppTheme resource.", info);
}
- switch (resource)
+ // Fallback to root object ResourceDictionary (e.g. page-level resources)
+ var rootProvider = serviceProvider.GetService(typeof(IRootObjectProvider)) as IRootObjectProvider;
+ var root = rootProvider?.RootObject;
+ if (root is IResourcesProvider rootResources && rootResources.IsResourcesCreated
+ && rootResources.Resources.TryGetValue(Key, out resource))
{
- case AppThemeColor color:
+ if (resource is AppThemeColor rootColor)
+ {
+ return rootColor.GetBinding();
+ }
+ if (resource is AppThemeObject rootTheme)
+ {
+ return rootTheme.GetBinding();
+ }
+ var info = (serviceProvider.GetService(typeof(IXmlLineInfoProvider)) as IXmlLineInfoProvider)?.XmlLineInfo;
+ throw new XamlParseException($"Resource found for key {Key} is not a valid AppTheme resource.", info);
+ }
+
+ if (Application.Current?.Resources.TryGetValueAndSource(Key, out resource, out _) == true)
+ {
+ if (resource is AppThemeColor color)
+ {
return color.GetBinding();
- case AppThemeObject themeResource:
- return themeResource.GetBinding();
- default:
- {
- var xmlLineInfo = serviceProvider.GetService(typeof(IXmlLineInfoProvider)) is IXmlLineInfoProvider xmlLineInfoProvider ? xmlLineInfoProvider.XmlLineInfo : null;
- throw new XamlParseException($"Resource found for key {Key} is not of type {nameof(AppThemeColor)} or {nameof(AppThemeObject)}", xmlLineInfo);
- }
+ }
+ if (resource is AppThemeObject theme)
+ {
+ return theme.GetBinding();
+ }
+ var info = (serviceProvider.GetService(typeof(IXmlLineInfoProvider)) as IXmlLineInfoProvider)?.XmlLineInfo;
+ throw new XamlParseException($"Resource found for key {Key} is not a valid AppTheme resource.", info);
}
+ var xmlInfo = (serviceProvider.GetService(typeof(IXmlLineInfoProvider)) as IXmlLineInfoProvider)?.XmlLineInfo;
+ throw new XamlParseException($"Resource not found for key {Key}.", xmlInfo);
}
- static bool TryGetResource(string key, IEnumerable