派生FixedDocument的序列化

本文关键字:序列化 FixedDocument 派生 | 更新日期: 2023-09-27 18:11:56

由于只能向FixedDocument添加页面,所以我编写了一个派生类:

public class CustomFixedDocument : FixedDocument
{
    public void RemoveChild(object child)
    {
        base.RemoveLogicalChild(child);
    }
}

来代替FixedDocument,它工作得很好,直到我尝试打印文档并收到以下错误:

类型的未处理异常"System.Windows.Xps。XpsSerializationException'发生在ReachFramework.dll

附加信息:此类型的对象没有序列化支持。

我过去没有那么多地使用过序列化,并且已经阅读了它,但仍然无法解决问题。我也试过

[Serializable]

属性,但没有任何区别。

谁能给我指路或者有什么好主意吗?

派生FixedDocument的序列化

如果您查看检查是否支持特定类型的方法的反编译源代码,您将大致看到以下内容:

internal bool IsSerializedObjectTypeSupported(object serializedObject)
{
  bool flag = false;
  Type type = serializedObject.GetType();
  if (this._isBatchMode)
  {
    if (typeof (Visual).IsAssignableFrom(type) && type != typeof (FixedPage))
      flag = true;
  }
  else if (type == typeof (FixedDocumentSequence) || type == typeof (FixedDocument) || (type == typeof (FixedPage) || typeof (Visual).IsAssignableFrom(type)) || typeof (DocumentPaginator).IsAssignableFrom(type))
    flag = true;
  return flag;
}

这里你可以看到这个类型要么继承DocumentPaginator, Visual,要么就是FixedDocument, FixedDocumentSequence, FixedPage类型。因此,从FixedDocument继承的类型将不起作用,无论您将使用什么序列化属性,因此您必须找到不同的方法。我认为这是XpsSerializationManager的一个bug,但也许有一些深层次的原因。

我决定尝试OP的方法,看看我是否能让它工作。

根据Evk发布的代码片段,虽然IsSerializedObjectTypeSupported()函数将不接受我们自己自定义的FixedDocument导数,但它将接受DocumentPaginator,并且XpsDocumentWriter.Write()的一个过载接受分页器,因此应该可以工作,对吗?

好吧,事实证明,如果你做XpsDocumentWriter.Write( myFixedDocument.DocumentPaginator )(其中myFixedDocumentFixedDocument的自定义衍生品),那么在库代码深处的某个地方会抛出NullReferenceException。所以,运气不好。

但是,根据相同的代码片段,FixedPage也是受支持的类型,并且XpsDocumentWriter.Write()方法有另一个重载,它接受FixedPage的单个实例。

所以,下面的代码为我工作:
foreach( FixedPage fixedPage in 
        fixedDocument.Pages.Select( pageContent => pageContent.Child ) )
    xpsDocumentWriter.Write( fixedPage );

(其中Select()来自using System.Linq)