public void Visit(ElementNode node, INode parentNode) { var value = Values[node]; XmlName propertyName; //Set RD to VE if (typeof(ResourceDictionary).IsAssignableFrom(Context.Types[node]) && 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); return; } } //Only proceed further if the node is a keyless RD if (parentNode is IElementNode && typeof(ResourceDictionary).IsAssignableFrom(Context.Types[((IElementNode)parentNode)]) && !((IElementNode)parentNode).Properties.ContainsKey(XmlName.xKey)) { node.Accept(new ApplyPropertiesVisitor(Context, stopOnResourceDictionary: false), parentNode); } else if (parentNode is ListNode && typeof(ResourceDictionary).IsAssignableFrom(Context.Types[((IElementNode)parentNode.Parent)]) && !((IElementNode)parentNode.Parent).Properties.ContainsKey(XmlName.xKey)) { node.Accept(new ApplyPropertiesVisitor(Context, stopOnResourceDictionary: false), parentNode); } }
public void Visit(MarkupNode markupnode, INode parentNode) { var parentElement = parentNode as IElementNode; XmlName propertyName; if (!ApplyPropertiesVisitor.TryGetPropertyName(markupnode, parentNode, out propertyName)) { return; } if (Skips.Contains(propertyName)) { return; } if (parentElement.SkipProperties.Contains(propertyName)) { return; } var markupString = markupnode.MarkupString; var node = ParseExpression(ref markupString, markupnode.NamespaceResolver, markupnode, markupnode, parentNode) as IElementNode; if (node != null) { ((IElementNode)parentNode).Properties[propertyName] = node; node.Parent = parentNode; } }
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 }); }
public void Visit(ListNode node, INode parentNode) { //this is a gross hack to keep ListNode alive. ListNode must go in favor of Properties XmlName name; if (ApplyPropertiesVisitor.TryGetPropertyName(node, parentNode, out name)) { node.XmlName = name; } }
public void Visit(ElementNode node, INode parentNode) { object value = null; XamlParseException xpe; var type = XamlParser.GetElementType(node.XmlType, node, Context.RootElement?.GetType().GetTypeInfo().Assembly, out xpe); if (type == null) { throw new ArgumentNullException(null, "type should not be null"); } if (xpe != null) { throw xpe; } Context.Types[node] = type; string ctorargname; if (IsXaml2009LanguagePrimitive(node)) { value = CreateLanguagePrimitive(type, node); } else if (node.Properties.ContainsKey(XmlName.xArguments) || node.Properties.ContainsKey(XmlName.xFactoryMethod)) { value = CreateFromFactory(type, node); } else if ( type.GetTypeInfo() .DeclaredConstructors.Any( ci => ci.IsPublic && ci.GetParameters().Length != 0 && ci.GetParameters().All(pi => pi.CustomAttributes.Any(attr => attr.AttributeType == typeof(ParameterAttribute)))) && ValidateCtorArguments(type, node, out ctorargname)) { value = CreateFromParameterizedConstructor(type, node); } else if (!type.GetTypeInfo().DeclaredConstructors.Any(ci => ci.IsPublic && ci.GetParameters().Length == 0) && !ValidateCtorArguments(type, node, out ctorargname)) { throw new XamlParseException($"The Property {ctorargname} is required to create a {type?.FullName} object.", node); } else { //this is a trick as the DataTemplate parameterless ctor is internal, and we can't CreateInstance(..., false) on WP7 try { if (type == typeof(DataTemplate)) { value = new DataTemplate(); } if (type == typeof(ControlTemplate)) { value = new ControlTemplate(); } if (value == null && node.CollectionItems.Any() && node.CollectionItems.First() is ValueNode) { var serviceProvider = new XamlServiceProvider(node, Context); var converted = ((ValueNode)node.CollectionItems.First()).Value.ConvertTo(type, () => type.GetTypeInfo(), serviceProvider); if (converted != null && converted.GetType() == type) { value = converted; } } if (value == null) { if (type.GetTypeInfo().DeclaredConstructors.Any(ci => ci.IsPublic && ci.GetParameters().Length == 0)) { //default constructor value = Activator.CreateInstance(type); } else { ConstructorInfo constructorInfo = null; //constructor with all default parameters foreach (var constructor in type.GetConstructors()) { if (!constructor.IsStatic) { bool areAllParamsDefault = true; foreach (var param in constructor.GetParameters()) { if (!param.HasDefaultValue) { areAllParamsDefault = false; break; } } if (areAllParamsDefault) { if (null == constructorInfo) { constructorInfo = constructor; } else { throw new XamlParseException($"{type.FullName} has more than one constructor which params are all default.", node); } } } } if (null == constructorInfo) { throw new XamlParseException($"{type.FullName} has no constructor which params are all default.", node); } List <object> defaultParams = new List <object>(); foreach (var param in constructorInfo.GetParameters()) { defaultParams.Add(param.DefaultValue); } value = Activator.CreateInstance(type, defaultParams.ToArray()); } if (value is Element element) { if (null != Application.Current) { Application.Current.XamlResourceChanged += element.OnResourcesChanged; } element.IsCreateByXaml = true; element.LineNumber = node.LineNumber; element.LinePosition = node.LinePosition; } } } catch (TargetInvocationException e) { if (e.InnerException is XamlParseException || e.InnerException is XmlException) { throw e.InnerException; } throw; } } Values[node] = value; var markup = value as IMarkupExtension; if (markup != null && (value is TypeExtension || value is StaticExtension || value is ArrayExtension)) { var serviceProvider = new XamlServiceProvider(node, Context); var visitor = new ApplyPropertiesVisitor(Context); foreach (var cnode in node.Properties.Values.ToList()) { cnode.Accept(visitor, node); } foreach (var cnode in node.CollectionItems) { cnode.Accept(visitor, node); } value = markup.ProvideValue(serviceProvider); INode xKey; if (!node.Properties.TryGetValue(XmlName.xKey, out xKey)) { xKey = null; } node.Properties.Clear(); node.CollectionItems.Clear(); if (xKey != null) { node.Properties.Add(XmlName.xKey, xKey); } Values[node] = value; } if (value is BindableObject) { NameScope.SetNameScope(value as BindableObject, node.Namescope); } }
public void Visit(ElementNode node, INode parentNode) { object value = null; XamlParseException xpe; var type = XamlParser.GetElementType(node.XmlType, node, Context.RootElement?.GetType().GetTypeInfo().Assembly, out xpe); if (type == null) { throw new ArgumentNullException(nameof(type)); } if (xpe != null) { throw xpe; } Context.Types[node] = type; string ctorargname; if (IsXaml2009LanguagePrimitive(node)) { value = CreateLanguagePrimitive(type, node); } else if (node.Properties.ContainsKey(XmlName.xArguments) || node.Properties.ContainsKey(XmlName.xFactoryMethod)) { value = CreateFromFactory(type, node); } else if ( type.GetTypeInfo() .DeclaredConstructors.Any( ci => ci.IsPublic && ci.GetParameters().Length != 0 && ci.GetParameters().All(pi => pi.CustomAttributes.Any(attr => attr.AttributeType == typeof(ParameterAttribute)))) && ValidateCtorArguments(type, node, out ctorargname)) { value = CreateFromParameterizedConstructor(type, node); } else if (!type.GetTypeInfo().DeclaredConstructors.Any(ci => ci.IsPublic && ci.GetParameters().Length == 0) && !ValidateCtorArguments(type, node, out ctorargname)) { throw new XamlParseException($"The Property {ctorargname} is required to create a {type?.FullName} object.", node); } else { //this is a trick as the DataTemplate parameterless ctor is internal, and we can't CreateInstance(..., false) on WP7 try { if (type == typeof(DataTemplate)) { value = new DataTemplate(); } if (type == typeof(ControlTemplate)) { value = new ControlTemplate(); } if (value == null && node.CollectionItems.Any() && node.CollectionItems.First() is ValueNode) { var serviceProvider = new XamlServiceProvider(node, Context); var converted = ((ValueNode)node.CollectionItems.First()).Value.ConvertTo(type, () => type.GetTypeInfo(), serviceProvider); if (converted != null && converted.GetType() == type) { value = converted; } } if (value == null) { if (type.GetTypeInfo().DeclaredConstructors.Any(ci => ci.IsPublic && ci.GetParameters().Length == 0)) { //default constructor value = Activator.CreateInstance(type); } else { //constructor with all default parameters value = Activator.CreateInstance(type, BindingFlags.CreateInstance | BindingFlags.Public | BindingFlags.Instance | BindingFlags.OptionalParamBinding, null, new object[] { Type.Missing }, CultureInfo.CurrentCulture); } if (value is Element) { if (null != Application.Current) { Application.AddResourceChangedCallback(value, (value as Element).OnResourcesChanged); } if (value is BindableObject) { ((BindableObject)value).IsCreateByXaml = true; } } } } catch (TargetInvocationException e) { if (e.InnerException is XamlParseException || e.InnerException is XmlException) { throw e.InnerException; } throw; } } Values[node] = value; var markup = value as IMarkupExtension; if (markup != null && (value is TypeExtension || value is StaticExtension || value is ArrayExtension)) { var serviceProvider = new XamlServiceProvider(node, Context); var visitor = new ApplyPropertiesVisitor(Context); foreach (var cnode in node.Properties.Values.ToList()) { cnode.Accept(visitor, node); } foreach (var cnode in node.CollectionItems) { cnode.Accept(visitor, node); } value = markup.ProvideValue(serviceProvider); INode xKey; if (!node.Properties.TryGetValue(XmlName.xKey, out xKey)) { xKey = null; } node.Properties.Clear(); node.CollectionItems.Clear(); if (xKey != null) { node.Properties.Add(XmlName.xKey, xKey); } Values[node] = value; } if (value is BindableObject) { NameScope.SetNameScope(value as BindableObject, node.Namescope); } }