FlowDocument
メモリが不足するため、大きなドキュメントを生成するためにシングルを使用することはできません。ただし、出力をシーケンスFlowDocument
または非常に高いものとして生成できる場合ItemsControl
は、可能です。
これを行う最も簡単な方法はDocumentPaginator
、サブクラスを作成して、サブクラスのインスタンスを に渡すことXpsDocumentWriter.Write
です。
var document = new XpsDocument(...);
var writer = XpsDocument.CreateXpsDocumentWriter(xpsDocument);
writer.Write(new WidgetPaginator { Widget = widgetBeingPrinted, PageSize = ... });
WidgetPaginator
クラス自体は非常に単純です。
class WidgetPaginator : DocumentPaginator, IDocumentPaginatorSource
{
Size _pageSize;
public Widget Widget { get; set; }
public override Size PageSize { get { return _pageSize; } set { _pageSize = value; } }
public override bool IsPageCountValid { return true; }
public override IDocumentPaginatorSource Source { return this; }
public override DocumentPaginator DocumentPaginator { return this; }
public override int PageCount
{
get
{
return ...; // Compute page count
}
}
public override DocumentPage GetPaget(int pageNumber)
{
var visual = ...; // Compute page visual
Rect box = new Rect(0,0,_pageSize.With, _pageSize.Height);
return new DocumentPage(visual, _pageSize, box, box);
}
もちろん、実際にページを作成するコードを作成する必要があります。
一連の FlowDocuments を使用してドキュメントを作成する場合
一連のFlowDocuments
ドキュメントを一度にではなく 1 セクションずつレイアウトするために使用している場合、カスタム ページネーターは 2 つのパスで機能します。
- 最初のパスは、ページネーターが構築されるときに発生します。
FlowDocument
セクションごとに を作成し、DocumentPaginator
を取得してページ数を取得します。FlowDocument
ページがカウントされた後、各セクションは破棄されます。
- 2 番目のパスは、実際のドキュメント出力中に発生します。渡された番号が
GetPage()
最近FlowDocument
作成されたものである場合、GetPage()
そのドキュメントの paginator を呼び出して適切なページを取得します。それ以外の場合は、その FlowDocument を破棄しFlowDocument
、新しいセクションのを作成し、そのページネーターを取得してから、ページネーターを呼び出しGetPage()
ます。
FlowDocuments
この戦略では、データをそれぞれ独自のドキュメントを持つ「セクション」に分割できる限り、これまでと同じように使用し続けることができます。カスタム ページネーターは、個々のすべての FlowDocuments を 1 つの大きなドキュメントとして効果的に扱います。これは、Word の「マスター ドキュメント」機能に似ています。
垂直に積み重ねられたビジュアルのシーケンスとしてデータをレンダリングできる場合
この場合、同じ手法を使用できます。最初のパスでは、すべてのビジュアルが順番に生成され、ページに収まる数が測定されます。データ構造は、特定のページで見つかったビジュアルの範囲を (インデックスなどによって) 示すために構築されます。このプロセスの間、ページがいっぱいになるたびに、次のビジュアルが新しいページに配置されます。ヘッダーとフッターは当然の方法で処理されます。
実際のドキュメント生成中GetPage()
に、特定のページにあると以前に決定されたビジュアルを再生成し、垂直 DockPanel または選択した他のパネルを使用してそれらを結合するメソッドが実装されます。
の制限に対処する必要がないため、この手法は長期的にはより柔軟であることがわかりましたFlowDocument
。