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/FillResourceDictionariesVisitor.cs | |
download | xamarin-forms-17fdde66d94155fc62a034fa6658995bef6fd6e5.tar.gz xamarin-forms-17fdde66d94155fc62a034fa6658995bef6fd6e5.tar.bz2 xamarin-forms-17fdde66d94155fc62a034fa6658995bef6fd6e5.zip |
Initial import
Diffstat (limited to 'Xamarin.Forms.Xaml/FillResourceDictionariesVisitor.cs')
-rw-r--r-- | Xamarin.Forms.Xaml/FillResourceDictionariesVisitor.cs | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/Xamarin.Forms.Xaml/FillResourceDictionariesVisitor.cs b/Xamarin.Forms.Xaml/FillResourceDictionariesVisitor.cs new file mode 100644 index 00000000..5eb47887 --- /dev/null +++ b/Xamarin.Forms.Xaml/FillResourceDictionariesVisitor.cs @@ -0,0 +1,127 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Reflection; +using Xamarin.Forms.Xaml.Internals; + +namespace Xamarin.Forms.Xaml +{ + internal class FillResourceDictionariesVisitor : IXamlNodeVisitor + { + public FillResourceDictionariesVisitor(HydratationContext context) + { + Context = context; + } + + HydratationContext Context { get; } + + Dictionary<INode, object> Values + { + get { return Context.Values; } + } + + public bool VisitChildrenFirst + { + get { return false; } + } + + public bool StopOnDataTemplate + { + get { return true; } + } + + public bool StopOnResourceDictionary + { + get { return false; } + } + + public void Visit(ValueNode node, INode parentNode) + { + } + + public void Visit(MarkupNode node, INode parentNode) + { + } + + public void Visit(ElementNode node, INode parentNode) + { + if (node.SkipPrefix(node.NamespaceResolver.LookupPrefix(node.NamespaceURI))) + return; + + var value = Values[node]; + var parentElement = parentNode as IElementNode; + var markupExtension = value as IMarkupExtension; + var valueProvider = value as IValueProvider; + + //Set Resources in ResourcesDictionaries + if (IsCollectionItem(node, parentNode) && parentNode is IElementNode) + { + if (typeof (IEnumerable).GetTypeInfo().IsAssignableFrom(Context.Types[parentElement].GetTypeInfo())) + { + var source = Values[parentNode]; + if (Context.Types[parentElement] == typeof (ResourceDictionary) && value is Style && + !node.Properties.ContainsKey(XmlName.xKey)) + { + node.Accept(new ApplyPropertiesVisitor(Context), parentNode); + if (markupExtension != null) + { + var serviceProvider = new XamlServiceProvider(node, Context); + value = markupExtension.ProvideValue(serviceProvider); + } + if (valueProvider != null) + { + var serviceProvider = new XamlServiceProvider(node, Context); + value = valueProvider.ProvideValue(serviceProvider); + } + ((ResourceDictionary)source).Add(value as Style); + } + else if (Context.Types[parentElement] == typeof (ResourceDictionary) && !node.Properties.ContainsKey(XmlName.xKey)) + throw new XamlParseException("resources in ResourceDictionary require a x:Key attribute", node); + else if (Context.Types[parentElement] == typeof (ResourceDictionary) && node.Properties.ContainsKey(XmlName.xKey)) + { + node.Accept(new ApplyPropertiesVisitor(Context), parentNode); + if (markupExtension != null) + { + var serviceProvider = new XamlServiceProvider(node, Context); + value = markupExtension.ProvideValue(serviceProvider); + } + if (valueProvider != null) + { + var serviceProvider = new XamlServiceProvider(node, Context); + value = valueProvider.ProvideValue(serviceProvider); + } + ((ResourceDictionary)source).Add((string)(((ValueNode)node.Properties[XmlName.xKey]).Value), value); + } + } + } + + //Set RD to VE + XmlName propertyName; + if (ApplyPropertiesVisitor.TryGetPropertyName(node, parentNode, out propertyName)) + { + if ((propertyName.LocalName == "Resources" || + propertyName.LocalName.EndsWith(".Resources", StringComparison.Ordinal)) && value is ResourceDictionary) + { + var source = Values[parentNode]; + ApplyPropertiesVisitor.SetPropertyValue(source, propertyName, value, Context.RootElement, node, Context, node); + } + } + } + + public void Visit(RootNode node, INode parentNode) + { + } + + public void Visit(ListNode node, INode parentNode) + { + } + + static bool IsCollectionItem(INode node, INode parentNode) + { + var parentList = parentNode as IListNode; + if (parentList == null) + return false; + return parentList.CollectionItems.Contains(node); + } + } +}
\ No newline at end of file |