| File: MarkupExtensions\StaticResourceExtension.cs | Web Access |
| Project: src\src\Controls\src\Xaml\Controls.Xaml.csproj (Microsoft.Maui.Controls.Xaml) |
using System; using System.Collections.Generic; using System.Reflection; using Microsoft.Maui.Controls.Xaml.Internals; namespace Microsoft.Maui.Controls.Xaml { [ContentProperty(nameof(Key))] [RequireService([typeof(IXmlLineInfoProvider), typeof(IProvideParentValues)])] [ProvideCompiled("Microsoft.Maui.Controls.Build.Tasks.StaticResourceExtension")] public sealed class StaticResourceExtension : IMarkupExtension { public string Key { get; set; } public object ProvideValue(IServiceProvider serviceProvider) { if (serviceProvider is null) throw new ArgumentNullException(nameof(serviceProvider)); if (Key is null) throw new XamlParseException("you must specify a key in {StaticResource}", serviceProvider); if (serviceProvider.GetService(typeof(IProvideValueTarget)) is not IProvideParentValues valueProvider) throw new ArgumentException(null, nameof(serviceProvider)); if (!TryGetResource(Key, valueProvider.ParentObjects, out var resource, out var resourceDictionary) && !TryGetApplicationLevelResource(Key, out resource, out resourceDictionary)) { var xmlLineInfo = serviceProvider.GetService(typeof(IXmlLineInfoProvider)) is IXmlLineInfoProvider xmlLineInfoProvider ? xmlLineInfoProvider.XmlLineInfo : null; throw new XamlParseException($"StaticResource not found for key {Key}", xmlLineInfo); } Diagnostics.ResourceDictionaryDiagnostics.OnStaticResourceResolved(resourceDictionary, Key, valueProvider.TargetObject, valueProvider.TargetProperty); return CastTo(resource, valueProvider.TargetProperty); } //used by X.HR.F internal static object CastTo(object value, object targetProperty) { var bp = targetProperty as BindableProperty; var pi = targetProperty as PropertyInfo; Type valueType = value.GetType(); var propertyType = bp?.ReturnType ?? pi?.PropertyType; if (propertyType is null || propertyType.IsAssignableFrom(valueType)) return value; if (TypeConversionHelper.TryConvert(value, propertyType, out var convertedValue)) { return convertedValue; } return value; } static bool TryGetResource(string key, IEnumerable<object> parentObjects, out object resource, out ResourceDictionary resourceDictionary) { resource = null; resourceDictionary = null; foreach (var p in parentObjects) { var resDict = p is IResourcesProvider irp && irp.IsResourcesCreated ? irp.Resources : p as ResourceDictionary; if (resDict == null) continue; if (resDict.TryGetValueAndSource(key, out resource, out resourceDictionary)) return true; } return false; } static bool TryGetApplicationLevelResource(string key, out object resource, out ResourceDictionary resourceDictionary) { resource = null; resourceDictionary = null; return Application.Current != null && ((IResourcesProvider)Application.Current).IsResourcesCreated && Application.Current.Resources.TryGetValueAndSource(key, out resource, out resourceDictionary); } } }