Сериализация WPF-компонента с использованием XamlWriter без конструктора по умолчанию
Я обнаружил, что вы можете сериализовать компонент wpf, в моем примере FixedDocument
, с использованием XamlWriter
и MemoryStream
:
FixedDocument doc = GetDocument();
MemoryStream stream = new MemoryStream();
XamlWriter.Save(doc, stream);
А потом вернуть его обратно:
stream.Seek(0, SeekOrigin.Begin);
FixedDocument result = (FixedDocument)XamlReader.Load(stream);
return result;
Тем не менее, теперь мне нужно иметь возможность сериализовать DocumentPage
также. Который испытывает недостаток в конструкторе по умолчанию, который делает XamlReader.Load
вызов бросить исключение.
Есть ли способ сериализации компонента wpf без конструктора по умолчанию?
1 ответ
Вот одна из техник.
Сначала создайте MarkupExtension, которое может создать желаемый класс. Супер-простой будет:
public class DocumentPageExtension : MarkupExtension
{
public Visual Visual { get; set; }
public Size PageSize { get; set; }
public Rect BleedBox { get; set; }
public Rect ContentBox { get; set; }
public override object ProvideValue(IServiceProvider serviceProvider)
{
return new DocumentPage(Visual, PageSize, BleedBox, ContentBox);
}
}
Теперь, после того как XamlWriter запишет ваш документ, просто замените "DocumentPage" на "my:DocumentPageExtension", добавив соответствующее объявление пространства имен в верхней части файла.
Полученный файл должен быть доступен для чтения XamlReader.Load
,
Возможно, что XamlWriter не хранит значения свойств, доступных только для чтения, таких как свойства, найденные в DocumentPage. (Я почти всегда использую замену XamlWriter, которую я написал некоторое время назад.) Если он вообще не сериализует эти свойства, метод, приведенный здесь, необходимо будет дополнить некоторым другим способом получения этих значений свойств в XAML в первом место.
Также обратите внимание, что можно вызывать общий вызов конструктора MarkupExtension, а не "специальный корпус" для каждого объекта, который требует обработки таким образом.