diff options
Diffstat (limited to 'Xamarin.Forms.Xaml/ApplyPropertiesVisitor.cs')
-rw-r--r-- | Xamarin.Forms.Xaml/ApplyPropertiesVisitor.cs | 55 |
1 files changed, 19 insertions, 36 deletions
diff --git a/Xamarin.Forms.Xaml/ApplyPropertiesVisitor.cs b/Xamarin.Forms.Xaml/ApplyPropertiesVisitor.cs index 833d5d94..154ba023 100644 --- a/Xamarin.Forms.Xaml/ApplyPropertiesVisitor.cs +++ b/Xamarin.Forms.Xaml/ApplyPropertiesVisitor.cs @@ -35,10 +35,15 @@ namespace Xamarin.Forms.Xaml HydratationContext Context { get; } - public TreeVisitingMode VisitingMode => TreeVisitingMode.BottomUp; - public bool StopOnDataTemplate => true; + public bool VisitChildrenFirst { + get { return true; } + } + + public bool StopOnDataTemplate { + get { return true; } + } + public bool StopOnResourceDictionary { get; } - public bool VisitNodeOnDataTemplate => true; public void Visit(ValueNode node, INode parentNode) { @@ -76,15 +81,6 @@ namespace Xamarin.Forms.Xaml public void Visit(ElementNode node, INode parentNode) { - var propertyName = XmlName.Empty; - if (TryGetPropertyName(node, parentNode, out propertyName) && propertyName == XmlName._CreateContent){ - var s0 = Values[parentNode]; - if (s0 is ElementTemplate) { - SetTemplate(s0 as ElementTemplate, node); - return; - } - } - var value = Values [node]; var parentElement = parentNode as IElementNode; var markupExtension = value as IMarkupExtension; @@ -100,7 +96,7 @@ namespace Xamarin.Forms.Xaml value = valueProvider.ProvideValue(serviceProvider); } - propertyName = XmlName.Empty; + XmlName propertyName = XmlName.Empty; //Simplify ListNodes with single elements var pList = parentNode as ListNode; @@ -117,11 +113,15 @@ namespace Xamarin.Forms.Xaml return; var source = Values [parentNode]; - SetPropertyValue(source, propertyName, value, Context.RootElement, node, Context, node); + + if (propertyName == XmlName._CreateContent && source is ElementTemplate) + SetTemplate(source as ElementTemplate, node); + else + SetPropertyValue(source, propertyName, value, Context.RootElement, node, Context, node); } else if (IsCollectionItem(node, parentNode) && parentNode is IElementNode) { // Collection element, implicit content, or implicit collection element. string contentProperty; - if (typeof(IEnumerable).GetTypeInfo().IsAssignableFrom(Context.Types [parentElement].GetTypeInfo()) && Context.Types[parentElement].GetRuntimeMethods().Any(mi => mi.Name == "Add" && mi.GetParameters().Length == 1)) { + if (typeof(IEnumerable).GetTypeInfo().IsAssignableFrom(Context.Types [parentElement].GetTypeInfo())) { var source = Values [parentNode]; if (!(typeof(ResourceDictionary).IsAssignableFrom(Context.Types [parentElement]))) { var addMethod = @@ -137,8 +137,7 @@ namespace Xamarin.Forms.Xaml var source = Values [parentNode]; SetPropertyValue(source, name, value, Context.RootElement, node, Context, node); - } else - throw new XamlParseException($"Can not set the content of {((IElementNode)parentNode).XmlType.Name} as it doesn't have a ContentPropertyAttribute", node); + } } else if (IsCollectionItem(node, parentNode) && parentNode is ListNode) { var parentList = (ListNode)parentNode; var source = Values [parentNode.Parent]; @@ -297,7 +296,7 @@ namespace Xamarin.Forms.Xaml return; //If we can assign that value to a normal property, let's do it - if (xpe == null && TrySetProperty(xamlelement, localName, value, lineInfo, serviceProvider, context, out xpe)) + if (xpe == null && TrySetProperty(xamlelement, localName, value, lineInfo, serviceProvider, out xpe)) return; //If it's an already initialized property, add to it @@ -362,7 +361,7 @@ namespace Xamarin.Forms.Xaml exception = null; var elementType = element.GetType(); - var binding = value.ConvertTo(typeof(BindingBase),pinfoRetriever:null,serviceProvider:null) as BindingBase; + var binding = value as BindingBase; var bindable = element as BindableObject; var nativeBindingService = DependencyService.Get<INativeBindingService>(); @@ -423,7 +422,7 @@ namespace Xamarin.Forms.Xaml return false; } - static bool TrySetProperty(object element, string localName, object value, IXmlLineInfo lineInfo, XamlServiceProvider serviceProvider, HydratationContext context, out Exception exception) + static bool TrySetProperty(object element, string localName, object value, IXmlLineInfo lineInfo, XamlServiceProvider serviceProvider, out Exception exception) { exception = null; @@ -433,9 +432,6 @@ namespace Xamarin.Forms.Xaml if (propertyInfo == null || !propertyInfo.CanWrite || (setter = propertyInfo.SetMethod) == null) return false; - if (!IsVisibleFrom(setter, context.RootElement)) - return false; - object convertedValue = value.ConvertTo(propertyInfo.PropertyType, () => propertyInfo, serviceProvider); if (convertedValue != null && !propertyInfo.PropertyType.IsInstanceOfType(convertedValue)) return false; @@ -444,19 +440,6 @@ namespace Xamarin.Forms.Xaml return true; } - static bool IsVisibleFrom(MethodInfo setter, object rootElement) - { - if (setter.IsPublic) - return true; - if (setter.IsPrivate && setter.DeclaringType == rootElement.GetType()) - return true; - if ((setter.IsAssembly || setter.IsFamilyOrAssembly) && setter.DeclaringType.AssemblyQualifiedName == rootElement.GetType().AssemblyQualifiedName) - return true; - if (setter.IsFamily && setter.DeclaringType.IsAssignableFrom(rootElement.GetType())) - return true; - return false; - } - static bool TryAddToProperty(object element, string localName, object value, IXmlLineInfo lineInfo, XamlServiceProvider serviceProvider, out Exception exception) { exception = null; |