예제 #1
0
        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);
                    }
                }
            }
        }
예제 #2
0
        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);
                    }
                }
            }
        }