summaryrefslogtreecommitdiff
path: root/Xamarin.Forms.Xaml
diff options
context:
space:
mode:
authorStephane Delcroix <stephane@delcroix.org>2016-09-23 09:01:22 +0200
committerJason Smith <jason.smith@xamarin.com>2016-09-23 00:01:22 -0700
commita5183bed8d38db411549733934b53380b93773b5 (patch)
tree51953e228a71cb59600c8c5ab001a959ee811a27 /Xamarin.Forms.Xaml
parent1076e735697d393c7b10654f8dc7d9a91c7c13e1 (diff)
downloadxamarin-forms-a5183bed8d38db411549733934b53380b93773b5.tar.gz
xamarin-forms-a5183bed8d38db411549733934b53380b93773b5.tar.bz2
xamarin-forms-a5183bed8d38db411549733934b53380b93773b5.zip
[XamlC] Implement IValueProvider.PropertyType (#345)
Diffstat (limited to 'Xamarin.Forms.Xaml')
-rw-r--r--Xamarin.Forms.Xaml/MarkupExtensions/StaticResourceExtension.cs47
-rw-r--r--Xamarin.Forms.Xaml/XamlServiceProvider.cs22
2 files changed, 29 insertions, 40 deletions
diff --git a/Xamarin.Forms.Xaml/MarkupExtensions/StaticResourceExtension.cs b/Xamarin.Forms.Xaml/MarkupExtensions/StaticResourceExtension.cs
index cf672a3d..a7f59be8 100644
--- a/Xamarin.Forms.Xaml/MarkupExtensions/StaticResourceExtension.cs
+++ b/Xamarin.Forms.Xaml/MarkupExtensions/StaticResourceExtension.cs
@@ -11,7 +11,7 @@ namespace Xamarin.Forms.Xaml
public object ProvideValue(IServiceProvider serviceProvider)
{
if (serviceProvider == null)
- throw new ArgumentNullException("serviceProvider");
+ throw new ArgumentNullException(nameof(serviceProvider));
if (Key == null)
{
var lineInfoProvider = serviceProvider.GetService(typeof (IXmlLineInfoProvider)) as IXmlLineInfoProvider;
@@ -23,6 +23,7 @@ namespace Xamarin.Forms.Xaml
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)
{
@@ -30,35 +31,27 @@ namespace Xamarin.Forms.Xaml
var resDict = ve?.Resources ?? p as ResourceDictionary;
if (resDict == null)
continue;
- object res;
- if (resDict.TryGetValue(Key, out res))
- {
- return ConvertCompiledOnPlatform(res);
- }
- }
- if (Application.Current != null && Application.Current.Resources != null &&
- Application.Current.Resources.ContainsKey(Key))
- {
- var resource = Application.Current.Resources[Key];
-
- return ConvertCompiledOnPlatform(resource);
+ if (resDict.TryGetValue(Key, out resource))
+ break;
}
+ if (resource == null && Application.Current != null && Application.Current.Resources != null &&
+ Application.Current.Resources.ContainsKey(Key))
+ resource = Application.Current.Resources [Key];
- throw new XamlParseException($"StaticResource not found for key {Key}", xmlLineInfo);
- }
+ if (resource == null)
+ throw new XamlParseException($"StaticResource not found for key {Key}", xmlLineInfo);
- static object ConvertCompiledOnPlatform(object resource)
- {
- var actualType = resource.GetType();
- if (actualType.GetTypeInfo().IsGenericType && actualType.GetGenericTypeDefinition() == typeof(OnPlatform<>))
- {
- // If we're accessing OnPlatform via a StaticResource in compiled XAML
- // we'll have to handle the cast to the target type manually
- // (Normally the compiled XAML handles this by calling `implicit` explicitly,
- // but it doesn't know to do that when it's using a static resource)
- var method = actualType.GetRuntimeMethod("op_Implicit", new[] { actualType });
- resource = method.Invoke(resource, new[] { resource });
- }
+ var bp = valueProvider.TargetProperty as BindableProperty;
+ var pi = valueProvider.TargetProperty as PropertyInfo;
+ var propertyType = bp?.ReturnType ?? pi?.PropertyType;
+ if (propertyType == null)
+ return resource;
+ if (propertyType.IsAssignableFrom(resource.GetType()))
+ return resource;
+ var implicit_op = resource.GetType().GetRuntimeMethod("op_Implicit", new [] { resource.GetType() });
+ //This will invoke the op_implicit on OnPlatform<>
+ if (implicit_op != null && propertyType.IsAssignableFrom(implicit_op.ReturnType))
+ return implicit_op.Invoke(resource, new [] { resource });
return resource;
}
diff --git a/Xamarin.Forms.Xaml/XamlServiceProvider.cs b/Xamarin.Forms.Xaml/XamlServiceProvider.cs
index 77ed6345..5599cbbc 100644
--- a/Xamarin.Forms.Xaml/XamlServiceProvider.cs
+++ b/Xamarin.Forms.Xaml/XamlServiceProvider.cs
@@ -89,7 +89,7 @@ namespace Xamarin.Forms.Xaml.Internals
}
}
- internal class XamlValueTargetProvider : IProvideParentValues, IProvideValueTarget
+ class XamlValueTargetProvider : IProvideParentValues, IProvideValueTarget
{
public XamlValueTargetProvider(object targetObject, INode node, HydratationContext context, object targetProperty)
{
@@ -102,14 +102,8 @@ namespace Xamarin.Forms.Xaml.Internals
INode Node { get; }
HydratationContext Context { get; }
-
public object TargetObject { get; }
-
- public object TargetProperty
- {
- get { throw new NotImplementedException(); }
- private set { }
- }
+ public object TargetProperty { get; } = null;
IEnumerable<object> IProvideParentValues.ParentObjects
{
@@ -141,15 +135,17 @@ namespace Xamarin.Forms.Xaml.Internals
public class SimpleValueTargetProvider : IProvideParentValues, IProvideValueTarget
{
readonly object[] objectAndParents;
+ readonly object targetProperty;
- public SimpleValueTargetProvider(object[] objectAndParents)
+ public SimpleValueTargetProvider(object[] objectAndParents, object targetProperty)
{
if (objectAndParents == null)
- throw new ArgumentNullException("objectAndParents");
+ throw new ArgumentNullException(nameof(objectAndParents));
if (objectAndParents.Length == 0)
throw new ArgumentException();
this.objectAndParents = objectAndParents;
+ this.targetProperty = targetProperty;
}
IEnumerable<object> IProvideParentValues.ParentObjects
@@ -164,7 +160,7 @@ namespace Xamarin.Forms.Xaml.Internals
object IProvideValueTarget.TargetProperty
{
- get { throw new NotImplementedException(); }
+ get { return targetProperty; }
}
}
@@ -249,7 +245,7 @@ namespace Xamarin.Forms.Xaml.Internals
XmlType xmlType, IXmlLineInfo xmlInfo, Assembly currentAssembly, out XamlParseException exception);
}
- internal class XamlRootObjectProvider : IRootObjectProvider
+ class XamlRootObjectProvider : IRootObjectProvider
{
public XamlRootObjectProvider(object rootObject)
{
@@ -269,7 +265,7 @@ namespace Xamarin.Forms.Xaml.Internals
public IXmlLineInfo XmlLineInfo { get; }
}
- internal interface INameScopeProvider
+ interface INameScopeProvider
{
INameScope NameScope { get; }
}