// Note that this returns XamlMember which might not actually appear in XamlObjectReader. For example, XamlLanguage.Items won't be returned when there is no item in the collection. public static IEnumerable <XamlMember> GetAllObjectReaderMembersByType(this XamlType type, IValueSerializerContext vsctx) { if (type.HasPositionalParameters(vsctx)) { yield return(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(XamlLanguage.Arguments); } if (type.IsContentValue(vsctx)) { yield return(XamlLanguage.Initialization); yield break; } if (type.IsDictionary) { yield return(XamlLanguage.Items); yield break; } foreach (var m in type.GetAllMembers()) { // 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) { continue; } if (!m.IsWritePublic && !m.Type.IsXData && !m.Type.IsArray && !m.Type.IsCollection && !m.Type.IsDictionary) { continue; } yield return(m); } if (type.IsCollection) { yield return(XamlLanguage.Items); } }
static bool ExaminePositionalParametersApplicable(this XamlType type, IValueSerializerContext vsctx) { if (!type.IsMarkupExtension || type.UnderlyingType == null) { return(false); } var args = type.GetSortedConstructorArguments(); if (args == null) { return(false); } foreach (var arg in args) { if (arg.Type != null && !arg.Type.IsContentValue(vsctx)) { return(false); } } Type [] argTypes = (from arg in args select arg.Type.UnderlyingType).ToArray(); if (argTypes.Any(at => at == null)) { return(false); } var ci = type.UnderlyingType .GetTypeInfo() .GetConstructors().FirstOrDefault(c => c.GetParameters().Select(r => r.ParameterType).SequenceEqual(argTypes) ); return(ci != null); }