zourimusi's blog

作業メモとnanoblock関連

WPFのPrintDialogまとめ

1. PrintDialogを表示

 this._Dialog = new PrintDialog();
 if (this._Dialog.ShowDialog() == true) { }

 

2. PrintDialogから印刷範囲を取得

 var area = this._Dialog.PrintQueue.GetPrintCapabilities(this._Dialog.PrintTicket).PageImageableArea;

area.ExtentWidth : 印刷範囲の幅 [px]
area.ExtentHeight : 印刷範囲の高さ [px]
area.OriginWidth : 左側余白の幅 [px]
area.OriginHeight : 上側余白の幅 [px]

実行には「ReachFramework」への参照が必要です。PrintDialog.PrintDocumentは印刷する紙の左上端を起点とするため、そのまま印刷すると左側と上側が余白分だけ見切れてしまいます。

 

3. 印刷するドキュメントを作成

 FixedDocument document = new FixedDocument();

 var page = new FixedPage()
 {
     Width = area.ExtentWidth + area.OriginWidth,
     Height = area.ExtentHeight + area.OriginHeight,
 };
 page.Children.Add(element);

 var content = new PageContent();
 ((IAddChild)content).AddChild(page);
 document.Pages.Add(content); 

FixedPageのサイズには初期値が指定されているようで、印刷範囲を指定しない限り目的のサイズで印刷することができません。これを指定しない場合、たとえば印刷設定で横を指定すると、縦の範囲しか印刷されていないかのように右側が大きく見切れてしまします。elementには左上にareaから取得した余白分のマージンを指定しておけば、左上隅からの印刷が可能です。

XAML上に配置されているコントロールを印刷するときは、直接ページに追加するとVisualTreeの問題が発生するので、VisualBrushを使うと良いかもしれません。また、ドキュメントに複数のページを追加すれば、複数印刷が可能です。

 

4. 印刷を実行

 this._Dialog.PrintDocument(document.DocumentPaginator, "Test");

PrintDialogのインスタンスをどこかに残しておけば、ダイアログを表示したものと別のメソッドでも印刷は実行できるようです。