IEnumerable <XamlNodeMember> GetNodeMembers(XamlObject xobj, IValueSerializerContext vsctx) { var member = new XamlNodeMember(); // XData.XmlReader is not returned. if (ReferenceEquals(xobj.Type, XamlLanguage.XData)) { yield return(member.Set(xobj, XamlLanguage.XData.GetMember("Text"))); yield break; } // FIXME: find out why root Reference has PositionalParameters. if (xobj.Value != root && ReferenceEquals(xobj.Type, XamlLanguage.Reference)) { yield return(member.Set(xobj, XamlLanguage.PositionalParameters)); } else { var inst = xobj.Value; var atts = new KeyValuePair <AttachableMemberIdentifier, object> [AttachablePropertyServices.GetAttachedPropertyCount(inst)]; AttachablePropertyServices.CopyPropertiesTo(inst, atts, 0); XamlObject cobj = null; foreach (var p in atts) { var axt = ctx.GetXamlType(p.Key.DeclaringType); if (cobj == null) { cobj = new XamlObject(); } yield return(member.Set(cobj.Set(axt, p.Value), axt.GetAttachableMember(p.Key.MemberName))); } var type = xobj.Type; if (type.HasPositionalParameters(vsctx)) { yield return(member.Set(xobj, XamlLanguage.PositionalParameters)); yield break; } // Note that if the XamlType has the default constructor, we don't need "Arguments". IEnumerable <XamlMember> args = type.ConstructionRequiresArguments ? type.GetSortedConstructorArguments() : null; if (args != null && args.Any()) { yield return(member.Set(xobj, XamlLanguage.Arguments)); } if (type.IsContentValue(vsctx)) { yield return(member.Set(xobj, XamlLanguage.Initialization)); yield break; } if (type.IsDictionary) { yield return(member.Set(xobj, XamlLanguage.Items)); yield break; } var members = type.GetAllMembersAsList(); for (int i = 0; i < members.Count; i++) { var m = members[i]; // do not read constructor arguments twice (they are written inside Arguments). if (args != null && args.Contains(m)) { continue; } // do not return non-public members (of non-collection/xdata). Not sure why .NET filters out them though. if (!m.IsReadPublic || !m.ShouldSerialize(xobj.Value)) { continue; } if (!m.IsWritePublic && !m.Type.IsXData && !m.Type.IsArray && !m.Type.IsCollection && !m.Type.IsDictionary) { continue; } yield return(member.Set(xobj, m)); } if (type.IsCollection) { yield return(member.Set(xobj, XamlLanguage.Items)); } } }