private JObject GetJObjectFromMarkupExt (string strMarkup) { JObject result = null; XamlNodeStackItem obj, member; var posParams = new List<string>(); var stack = new List<XamlNodeStackItem>(); foreach (XamlNode node in GetMarkupExtParser().Parse(strMarkup, 0, 0)) { switch (node.NodeType) { case XamlNodeType.None: break; case XamlNodeType.StartObject: string ns = FindPrefixByNamespace(node.XamlType.PreferredXamlNamespace); stack.Add(new XamlNodeStackItem(node, new JObject(new JProperty(pnDollar, ns != "" ? string.Format("{0}:{1}", ns, node.XamlType.Name) : node.XamlType.Name)))); break; case XamlNodeType.GetObject: throw new NotImplementedException(); case XamlNodeType.EndObject: obj = stack.Last(); if (stack.Count == 1) result = obj.JObject; stack.RemoveAt(stack.Count - 1); if (stack.Count > 0) { member = stack.Last(); if (member.JProperty != null) member.JProperty.Value = FormatJObjectAsMarkupExt(obj.JObject); } break; case XamlNodeType.StartMember: obj = stack.Last(t => t.JObject != null); member = new XamlNodeStackItem(node, new JProperty(node.Member.Name, null)); obj.JObject.Add(member.JProperty); stack.Add(member); break; case XamlNodeType.EndMember: member = stack.Last(); if (member.JProperty.Name == XamlLanguage.PositionalParameters.Name) { obj = stack.Last(t => t.JObject != null); member.JProperty.Remove(); AddPositionalParams(obj, posParams); posParams.Clear(); } stack.RemoveAt(stack.Count - 1); break; case XamlNodeType.Value: member = stack.Last(); string value = string.Format(CultureInfo.InvariantCulture, "{0}", node.Value); if (member.JProperty.Name == XamlLanguage.PositionalParameters.Name) posParams.Add(value); else member.JProperty.Value = value; break; case XamlNodeType.NamespaceDeclaration: throw new NotImplementedException(); default: throw new InvalidOperationException(); } } return result; }
private static void AddPositionalParams (XamlNodeStackItem obj, List<string> posParams) { Type objType = obj.Node.XamlType.UnderlyingType; ParameterInfo[] constrParams = objType.GetConstructors() .Select(ci => ci.GetParameters()) .Single(prms => prms.Length == posParams.Count); for (int i = 0; i < constrParams.Length; i++) { string paramName = constrParams[i].Name; PropertyInfo paramProp = objType.GetProperties() .SingleOrDefault(p => p.GetCustomAttribute<ConstructorArgumentAttribute>() != null && p.GetCustomAttribute<ConstructorArgumentAttribute>().ArgumentName == paramName); if (paramProp != null) paramName = paramProp.Name; else paramName = char.ToUpper(paramName[0]) + paramName.Substring(1); obj.JObject.Add(new JProperty(paramName, posParams[i])); } }