IEnumerable <XamlNodeInfo> GetItemsNodes(XamlMember xm, XamlObject xobj) { var obj = xobj.GetRawValue(); if (obj == null) { yield break; } var ie = xobj.Type.Invoker.GetItems(obj); while (ie.MoveNext()) { var iobj = ie.Current; // If it is dictionary, then retrieve the key, and rewrite the item as the Value part. object ikey = null; if (xobj.Type.IsDictionary) { Type kvpType = iobj.GetType(); bool isNonGeneric = kvpType == typeof(DictionaryEntry); var kp = isNonGeneric ? null : kvpType.GetProperty("Key"); var vp = isNonGeneric ? null : kvpType.GetProperty("Value"); ikey = isNonGeneric ? ((DictionaryEntry)iobj).Key : kp.GetValue(iobj, null); iobj = isNonGeneric ? ((DictionaryEntry)iobj).Value : vp.GetValue(iobj, null); } var wobj = TypeExtensionMethods.GetExtensionWrapped(iobj); var xiobj = new XamlObject(GetType(wobj), wobj); if (ikey != null) { // Key member is written *inside* the item object. // // It is messy, but Key and Value are *sorted*. In most cases Key goes first, but for example PositionalParameters comes first. // To achieve this behavior, we compare XamlLanguage.Key and value's Member and returns in order. It's all nasty hack, but at least it could be achieved like this! var en = GetNodes(null, xiobj).ToArray(); yield return(en [0]); // StartObject var xknm = new XamlNodeMember(xobj, XamlLanguage.Key); var nodes1 = en.Skip(1).Take(en.Length - 2); var nodes2 = GetKeyNodes(ikey, xobj.Type.KeyType, xknm); foreach (var xn in EnumerateMixingMember(nodes1, XamlLanguage.Key, nodes2)) { yield return(xn); } yield return(en [en.Length - 1]); } else { foreach (var xn in GetNodes(null, xiobj)) { yield return(xn); } } } }
IEnumerable <XamlNodeInfo> GetItemsNodes(XamlMember xm, XamlObject xobj) { var obj = xobj.Value; if (obj == null) { yield break; } var ie = xobj.Type.Invoker.GetItems(obj); var node = new XamlNodeInfo(); var xiobj = new XamlObject(); while (ie.MoveNext()) { var iobj = ie.Current; // If it is dictionary, then retrieve the key, and rewrite the item as the Value part. object ikey = null; if (xobj.Type.IsDictionary) { Type kvpType = iobj.GetType(); bool isNonGeneric = kvpType == typeof(DictionaryEntry); var kp = isNonGeneric ? null : kvpType.GetRuntimeProperty("Key"); var vp = isNonGeneric ? null : kvpType.GetRuntimeProperty("Value"); ikey = isNonGeneric ? ((DictionaryEntry)iobj).Key : kp.GetValue(iobj, null); iobj = isNonGeneric ? ((DictionaryEntry)iobj).Value : vp.GetValue(iobj, null); } var wobj = TypeExtensionMethods.GetExtensionWrapped(iobj); xiobj.Set(GetType(wobj), wobj); if (ikey != null) { // TODO: do this without copying the XamlNodeInfo somehow? var en = GetNodes(null, xiobj).Select(c => c.Copy()).GetEnumerator(); en.MoveNext(); yield return(en.Current); // StartObject //var nodes1 = en.Skip (1).Take (en.Count - 2); var nodes1 = new List <XamlNodeInfo>(); while (en.MoveNext()) { nodes1.Add(en.Current); } var nodes2 = GetKeyNodes(ikey, xobj.Type.KeyType); // group the members then sort to put the key nodes in the correct order var grouped = GroupMemberNodes(nodes1.Take(nodes1.Count - 1).Concat(nodes2)).OrderBy(r => r.Item1, TypeExtensionMethods.MemberComparer); foreach (var item in grouped) { foreach (var n in item.Item2) { yield return(n); } } yield return(nodes1[nodes1.Count - 1]); // EndObject } else { foreach (var xn in GetNodes(null, xiobj, node: node)) { yield return(xn); } } } }