Я использую метод System.Xaml.XamlServices.Save
для сериализации объекта, который имеет свойства с общедоступными геттерами / приватными сеттерами, и по своему дизайну эти свойства игнорируются. Я попытался реализовать совет о том, как переопределить привязки XAML по умолчанию и сериализовать частные свойства, но по какой-то причине это не работает - эти свойства все еще игнорируются. Кто-нибудь может указать, что не так:
public class CustomXamlSchemaContext : XamlSchemaContext
{
protected override XamlType GetXamlType(string xamlNamespace, string name, params XamlType[] typeArguments)
{
var type = base.GetXamlType(xamlNamespace, name, typeArguments);
return new CustomXamlType(type.UnderlyingType, type.SchemaContext, type.Invoker);
}
}
public class CustomXamlType : XamlType
{
public CustomXamlType(Type underlyingType, XamlSchemaContext schemaContext, XamlTypeInvoker invoker) : base(underlyingType, schemaContext, invoker)
{
}
protected override bool LookupIsConstructible()
{
return true;
}
protected override XamlMember LookupMember(string name, bool skipReadOnlyCheck)
{
var member = base.LookupMember(name, skipReadOnlyCheck);
return new CustomXamlMember(member.Name, member.DeclaringType, member.IsAttachable);
}
}
public class CustomXamlMember : XamlMember
{
public CustomXamlMember(string name, XamlType declaringType, bool isAttachable) : base(name, declaringType, isAttachable)
{
}
protected override bool LookupIsReadOnly()
{
return false;
}
}
public static string Save(object instance)
{
var stringWriter1 = new StringWriter(CultureInfo.CurrentCulture);
var stringWriter2 = stringWriter1;
var settings = new XmlWriterSettings { Indent = true, OmitXmlDeclaration = true };
using (var writer = XmlWriter.Create(stringWriter2, settings))
{
Save(writer, instance);
}
return stringWriter1.ToString();
}
public static void Save(XmlWriter writer, object instance)
{
if (writer == null)
throw new ArgumentNullException("writer");
using (var xamlXmlWriter = new XamlXmlWriter(writer, new CustomXamlSchemaContext()))
{
XamlServices.Save(xamlXmlWriter, instance);
}
}
Имея вышеуказанный код инфраструктуры и класс
public class Class1
{
public string Property1 { get; private set; }
public string Property2 { get; set; }
public DateTime AddedProperty { get; set; }
}
и сериализация экземпляра этого класса с
var obj = new Class1 { Property1 = "value1", Property2 = "value2" };
var objString = Save(obj);
Я получаю результат
<Class1 AddedProperty="0001-01-01" Property2="value2" xmlns="clr-namespace:TestNamespace;assembly=Tests" />
там, где нет записи для Property1.
Что еще более интересно, ни одна из перегрузок не вызывается во время сериализации.