diff options
author | Jason Smith <jason.smith@xamarin.com> | 2016-03-22 13:02:25 -0700 |
---|---|---|
committer | Jason Smith <jason.smith@xamarin.com> | 2016-03-22 16:13:41 -0700 |
commit | 17fdde66d94155fc62a034fa6658995bef6fd6e5 (patch) | |
tree | b5e5073a2a7b15cdbe826faa5c763e270a505729 /Xamarin.Forms.Xaml/MarkupExtensionParser.cs | |
download | xamarin-forms-17fdde66d94155fc62a034fa6658995bef6fd6e5.tar.gz xamarin-forms-17fdde66d94155fc62a034fa6658995bef6fd6e5.tar.bz2 xamarin-forms-17fdde66d94155fc62a034fa6658995bef6fd6e5.zip |
Initial import
Diffstat (limited to 'Xamarin.Forms.Xaml/MarkupExtensionParser.cs')
-rw-r--r-- | Xamarin.Forms.Xaml/MarkupExtensionParser.cs | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/Xamarin.Forms.Xaml/MarkupExtensionParser.cs b/Xamarin.Forms.Xaml/MarkupExtensionParser.cs new file mode 100644 index 00000000..cb62e1d1 --- /dev/null +++ b/Xamarin.Forms.Xaml/MarkupExtensionParser.cs @@ -0,0 +1,80 @@ +using System; +using System.Reflection; + +namespace Xamarin.Forms.Xaml +{ + internal sealed class MarkupExtensionParser : MarkupExpressionParser, IExpressionParser<object> + { + IMarkupExtension markupExtension; + + public object Parse(string match, ref string remaining, IServiceProvider serviceProvider) + { + var typeResolver = serviceProvider.GetService(typeof (IXamlTypeResolver)) as IXamlTypeResolver; + + //shortcut for Binding and StaticResource, to avoid too many reflection calls. + if (match == "Binding") + markupExtension = new BindingExtension(); + else if (match == "TemplateBinding") + markupExtension = new TemplateBindingExtension(); + else if (match == "StaticResource") + markupExtension = new StaticResourceExtension(); + else + { + if (typeResolver == null) + return null; + Type type; + + //The order of lookup is to look for the Extension-suffixed class name first and then look for the class name without the Extension suffix. + if (!typeResolver.TryResolve(match + "Extension", out type) && !typeResolver.TryResolve(match, out type)) + { + var lineInfoProvider = serviceProvider.GetService(typeof (IXmlLineInfoProvider)) as IXmlLineInfoProvider; + var lineInfo = (lineInfoProvider != null) ? lineInfoProvider.XmlLineInfo : new XmlLineInfo(); + throw new XamlParseException(String.Format("MarkupExtension not found for {0}", match), lineInfo); + } + markupExtension = Activator.CreateInstance(type) as IMarkupExtension; + } + + if (markupExtension == null) + { + var lineInfoProvider = serviceProvider.GetService(typeof (IXmlLineInfoProvider)) as IXmlLineInfoProvider; + var lineInfo = (lineInfoProvider != null) ? lineInfoProvider.XmlLineInfo : new XmlLineInfo(); + throw new XamlParseException(String.Format("Missing public default constructor for MarkupExtension {0}", match), + lineInfo); + } + + char next; + if (remaining == "}") + return markupExtension.ProvideValue(serviceProvider); + + string piece; + while ((piece = GetNextPiece(ref remaining, out next)) != null) + HandleProperty(piece, serviceProvider, ref remaining, next != '='); + + return markupExtension.ProvideValue(serviceProvider); + } + + protected override void SetPropertyValue(string prop, string strValue, object value, IServiceProvider serviceProvider) + { + MethodInfo setter; + if (prop == null) + { + //implicit property + var t = markupExtension.GetType(); + prop = ApplyPropertiesVisitor.GetContentPropertyName(t.GetTypeInfo()); + if (prop == null) + return; + setter = t.GetRuntimeProperty(prop).SetMethod; + } + else + setter = markupExtension.GetType().GetRuntimeProperty(prop).SetMethod; + + if (value == null && strValue != null) + { + value = strValue.ConvertTo(markupExtension.GetType().GetRuntimeProperty(prop).PropertyType, + (Func<TypeConverter>)null, serviceProvider); + } + + setter.Invoke(markupExtension, new[] { value }); + } + } +}
\ No newline at end of file |