blob: 34f1c569375ada859cc8949b7906ff4b07bb260a (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
using System;
using System.Reflection;
namespace Xamarin.Forms.Xaml
{
[ContentProperty("Key")]
public sealed class StaticResourceExtension : IMarkupExtension
{
public string Key { get; set; }
public object ProvideValue(IServiceProvider serviceProvider)
{
if (serviceProvider == null)
throw new ArgumentNullException(nameof(serviceProvider));
if (Key == null) {
var lineInfoProvider = serviceProvider.GetService(typeof(IXmlLineInfoProvider)) as IXmlLineInfoProvider;
var lineInfo = (lineInfoProvider != null) ? lineInfoProvider.XmlLineInfo : new XmlLineInfo();
throw new XamlParseException("you must specify a key in {StaticResource}", lineInfo);
}
var valueProvider = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideParentValues;
if (valueProvider == null)
throw new ArgumentException();
var xmlLineInfoProvider = serviceProvider.GetService(typeof(IXmlLineInfoProvider)) as IXmlLineInfoProvider;
var xmlLineInfo = xmlLineInfoProvider != null ? xmlLineInfoProvider.XmlLineInfo : null;
object resource = null;
foreach (var p in valueProvider.ParentObjects) {
var ve = p as VisualElement;
var resDict = ve?.Resources ?? p as ResourceDictionary;
if (resDict == null)
continue;
if (resDict.TryGetMergedValue(Key, out resource))
break;
}
if (resource == null && (Application.Current == null || Application.Current.Resources == null ||
!Application.Current.Resources.TryGetMergedValue(Key, out resource)))
throw new XamlParseException($"StaticResource not found for key {Key}", xmlLineInfo);
var bp = valueProvider.TargetProperty as BindableProperty;
var pi = valueProvider.TargetProperty as PropertyInfo;
var propertyType = bp?.ReturnType ?? pi?.PropertyType;
if (propertyType == null) {
if (resource.GetType().GetTypeInfo().IsGenericType && (resource.GetType().GetGenericTypeDefinition() == typeof(OnPlatform<>) || resource.GetType().GetGenericTypeDefinition() == typeof(OnIdiom<>))) {
// This is only there to support our backward compat story with pre 2.3.3 compiled Xaml project who was not providing TargetProperty
var method = resource.GetType().GetRuntimeMethod("op_Implicit", new[] { resource.GetType() });
resource = method.Invoke(resource, new[] { resource });
}
return resource;
}
if (propertyType.IsAssignableFrom(resource.GetType()))
return resource;
var implicit_op = resource.GetType().GetRuntimeMethod("op_Implicit", new [] { resource.GetType() });
if (implicit_op != null && propertyType.IsAssignableFrom(implicit_op.ReturnType))
return implicit_op.Invoke(resource, new [] { resource });
return resource;
}
}
}
|