public bool IsResourceDictionary(ElementNode node) => false;
static bool IsVisualStateGroupList(ElementNode node) { return(node != null && node.XmlType.Name == "VisualStateGroup" && node.Parent is IListNode); }
public void Visit(ElementNode node, INode parentNode) => action(node, parentNode);
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 (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) { value = Activator.CreateInstance(type); } } 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); } }
static INode ReadNode(XmlReader reader, bool nested = false) { var skipFirstRead = nested; Debug.Assert(reader.NodeType == XmlNodeType.Element); var name = reader.Name; List <INode> nodes = new List <INode>(); INode node = null; while (skipFirstRead || reader.Read()) { skipFirstRead = false; switch (reader.NodeType) { case XmlNodeType.EndElement: Debug.Assert(reader.Name == name); if (nodes.Count == 0) //Empty element { return(null); } if (nodes.Count == 1) { return(nodes[0]); } return(new ListNode(nodes, (IXmlNamespaceResolver)reader, ((IXmlLineInfo)reader).LineNumber, ((IXmlLineInfo)reader).LinePosition)); case XmlNodeType.Element: var isEmpty = reader.IsEmptyElement && reader.Name == name; var elementName = reader.Name; var elementNsUri = reader.NamespaceURI; var elementXmlInfo = (IXmlLineInfo)reader; IList <KeyValuePair <string, string> > xmlns; var attributes = ParseXamlAttributes(reader, out xmlns); var prefixes = PrefixesToIgnore(xmlns); IList <XmlType> typeArguments = null; if (attributes.Any(kvp => kvp.Key == XmlName.xTypeArguments)) { typeArguments = ((ValueNode)attributes.First(kvp => kvp.Key == XmlName.xTypeArguments).Value).Value as IList <XmlType>; } node = new ElementNode(new XmlType(elementNsUri, elementName, typeArguments), elementNsUri, reader as IXmlNamespaceResolver, elementXmlInfo.LineNumber, elementXmlInfo.LinePosition); ((IElementNode)node).Properties.AddRange(attributes); (node.IgnorablePrefixes ?? (node.IgnorablePrefixes = new List <string>()))?.AddRange(prefixes); ParseXamlElementFor((IElementNode)node, reader); nodes.Add(node); if (isEmpty || nested) { return(node); } break; case XmlNodeType.Text: node = new ValueNode(reader.Value.Trim(), (IXmlNamespaceResolver)reader, ((IXmlLineInfo)reader).LineNumber, ((IXmlLineInfo)reader).LinePosition); nodes.Add(node); break; case XmlNodeType.Whitespace: break; default: Debug.WriteLine("Unhandled node {0} {1} {2}", reader.NodeType, reader.Name, reader.Value); break; } } throw new XamlParseException("Closing PropertyElement expected", (IXmlLineInfo)reader); }
public bool IsResourceDictionary(ElementNode node) => typeof(ResourceDictionary).IsAssignableFrom(Context.Types[node]);
public void Visit(ElementNode node, INode parentNode) { }
public bool IsResourceDictionary(ElementNode node) => Context.Types.TryGetValue(node, out var type) && typeof(ResourceDictionary).IsAssignableFrom(type);
public void Visit(ElementNode node, INode parentNode) { XmlName propertyName; if (TryGetPropertyName(node, parentNode, out propertyName) && propertyName == XmlName._CreateContent) { var s0 = Values[parentNode]; if (s0 is ElementTemplate) { SetTemplate(s0 as ElementTemplate, node); return; } } var parentElement = parentNode as IElementNode; propertyName = XmlName.Empty; //Simplify ListNodes with single elements var pList = parentNode as ListNode; if (pList != null && pList.CollectionItems.Count == 1) { propertyName = pList.XmlName; parentNode = parentNode.Parent; parentElement = parentNode as IElementNode; } if (!Values.TryGetValue(node, out var value) && Context.ExceptionHandler != null) { return; } if (propertyName != XmlName.Empty || TryGetPropertyName(node, parentNode, out propertyName)) { if (Skips.Contains(propertyName)) { return; } if (parentElement == null) { return; } if (parentElement.SkipProperties.Contains(propertyName)) { return; } if (!Values.TryGetValue(parentNode, out var source) && Context.ExceptionHandler != null) { return; } ProvideValue(ref value, node, source, propertyName); SetPropertyValue(source, propertyName, value, Context.RootElement, node, Context, node); } else if (IsCollectionItem(node, parentNode) && parentNode is IElementNode) { if (!Values.TryGetValue(parentNode, out var source) && Context.ExceptionHandler != null) { return; } ProvideValue(ref value, node, source, XmlName.Empty); string contentProperty; Exception xpe = null; var xKey = node.Properties.ContainsKey(XmlName.xKey) ? ((ValueNode)node.Properties[XmlName.xKey]).Value as string : null; //ResourceDictionary if (xpe == null && TryAddToResourceDictionary(source as ResourceDictionary, value, xKey, node, out xpe)) { return; } // Dictionary with string key if (xpe == null && xKey != null) { var indexer = GetIndexer(source, typeof(string), value.GetType()); if (indexer != null) { indexer.SetValue(source, value, new[] { xKey }); return; } } // Collection element, implicit content, or implicit collection element. if (xpe == null && typeof(IEnumerable).IsAssignableFrom(Context.Types[parentElement]) && Context.Types[parentElement].GetRuntimeMethods().Any(mi => mi.Name == "Add" && mi.GetParameters().Length == 1)) { var addMethod = Context.Types[parentElement].GetRuntimeMethods().First(mi => mi.Name == "Add" && mi.GetParameters().Length == 1); addMethod?.Invoke(source, new[] { value }); return; } if (xpe == null && Context.Types[parentElement].GetRuntimeMethods().Any (mi => mi.Name == "Add" && mi.GetParameters().Length == 1 && mi.GetParameters()[0].ParameterType.IsAssignableFrom(value.GetType()))) { //if there are similar parameters in the function, this will exist issue. var addMethod = Context.Types[parentElement].GetRuntimeMethods().First(mi => mi.Name == "Add" && mi.GetParameters().Length == 1); if (addMethod != null) { addMethod.Invoke(source, new[] { value }); } return; } if (xpe == null && (contentProperty = GetContentPropertyName(Context.Types[parentElement].GetTypeInfo())) != null) { var name = new XmlName(node.NamespaceURI, contentProperty); if (Skips.Contains(name)) { return; } if (parentElement.SkipProperties.Contains(propertyName)) { return; } SetPropertyValue(source, name, value, Context.RootElement, node, Context, node); return; } xpe = xpe ?? new XamlParseException($"Can not set the content of {((IElementNode)parentNode).XmlType.Name} as it doesn't have a ContentPropertyAttribute", node); if (Context.ExceptionHandler != null) { Context.ExceptionHandler(xpe); } else { throw xpe; } } else if (IsCollectionItem(node, parentNode) && parentNode is ListNode) { if (!Values.TryGetValue(parentNode.Parent, out var source) && Context.ExceptionHandler != null) { return; } ProvideValue(ref value, node, source, XmlName.Empty); var parentList = (ListNode)parentNode; if (Skips.Contains(parentList.XmlName)) { return; } Exception xpe = null; var xKey = node.Properties.ContainsKey(XmlName.xKey) ? ((ValueNode)node.Properties[XmlName.xKey]).Value as string : null; object _; var collection = GetPropertyValue(source, parentList.XmlName, Context, parentList, out _) as IEnumerable; if (collection == null) { xpe = new XamlParseException($"Property {parentList.XmlName.LocalName} is null or is not IEnumerable", node); } if (xpe == null && TryAddToResourceDictionary(collection as ResourceDictionary, value, xKey, node, out xpe)) { return; } MethodInfo addMethod; if (xpe == null && (addMethod = collection.GetType().GetRuntimeMethods().First(mi => mi.Name == "Add" && mi.GetParameters().Length == 1)) != null) { addMethod.Invoke(collection, new[] { value }); return; } xpe = xpe ?? new XamlParseException($"Value of {parentList.XmlName.LocalName} does not have a Add() method", node); if (Context.ExceptionHandler != null) { Context.ExceptionHandler(xpe); } else { throw xpe; } } }
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) { 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); } }