WPFでの印刷ではUIElement
の派生クラスをもちいて行うのが基本(?)ですが、DrawingContext
を利用することで、従来のGDIを利用した描画ライクな手法で印刷を行うことができます。
DrawingContext を用いた印刷のサンプル
前回とほぼ同様のイメージを印刷するサンプル。
// FormattedText の生成
private FormattedText CreateFormatedText(string s, double width, TextAlignment align)
{
FormattedText fmtText = new FormattedText(
s,
System.Globalization.CultureInfo.CurrentCulture,
System.Windows.FlowDirection.LeftToRight,
new Typeface("MS Pゴシック"),
24.0d,Brushes.Black);
fmtText.MaxTextWidth = width;
fmtText.TextAlignment = align;
return fmtText;
}
// ページの描画
private void DrawPage(DrawingContext dc)
{
// Lineの描画
for (int i = 0; i < 10; i++)
{
Pen pen = new Pen(Brushes.Black, 1.0d + (i * 0.5d));
dc.DrawLine(pen, new Point(100.0d, 100.0d + (i * 10.0d)),
new Point(200.0d, 100.0d + (i * 10.0d)));
}
// 矩形の描画
dc.DrawRectangle(Brushes.Blue, new Pen(Brushes.Black, 1.0d),
new Rect(250.0d, 100.0d, 100.0d, 100.0d));
// 円の描画
dc.DrawEllipse(Brushes.Green, new Pen(Brushes.Black, 1.0d),
new Point(450.0d, 150.0d), 50.0d, 50.0d);
// ジオメトリの描画
StreamGeometry sg1 = new StreamGeometry();
using (StreamGeometryContext ctx = sg1.Open())
{
ctx.BeginFigure(new Point(600.0d, 100.0d), true, true);
ctx.LineTo(new Point(650.0d, 180.0d), true, true);
ctx.LineTo(new Point(550.0d, 180.0d), true, true);
}
sg1.Freeze();
dc.DrawGeometry(Brushes.Red, new Pen(Brushes.Black, 2.0d), sg1);
StreamGeometry sg2 = new StreamGeometry();
using (StreamGeometryContext ctx = sg2.Open())
{
ctx.BeginFigure(new Point(550.0d, 120.0d), true, true);
ctx.LineTo(new Point(650.0d, 120.0d), true, true);
ctx.LineTo(new Point(600.0d, 200.0d), true, true);
}
sg2.Freeze();
dc.DrawGeometry(Brushes.Yellow, new Pen(Brushes.Black, 2.0d), sg2);
// イメージの描画
Uri imageUri = new Uri("file://c:/temp/CAT.JPG");
dc.DrawImage(new BitmapImage(imageUri), new Rect(100.0d, 250.0d, 100.0d, 100.0d));
// テキストの描画
dc.DrawRectangle(null, new Pen(Brushes.Black, 1.0d), new Rect(99.0d, 399.0d, 502.0d, 102.0d));
FormattedText fmtTextL = CreateFormatedText("左寄せ文字列", 500.0d, TextAlignment.Left);
dc.DrawText(fmtTextL, new Point(100.0d, 400.0d + (30.0d - fmtTextL.Height) / 2.0d));
FormattedText fmtTextC = CreateFormatedText("中央寄せ文字列", 500.0d, TextAlignment.Center);
dc.DrawText(fmtTextC, new Point(100.0d, 430.0d + (30.0d - fmtTextC.Height) / 2.0d));
FormattedText fmtTextR = CreateFormatedText("右寄せ文字列", 500.0d, TextAlignment.Right);
dc.DrawText(fmtTextR, new Point(100.0d, 460.0d + (30.0d - fmtTextR.Height) / 2.0d));
}
// 印刷処理
private void PrintPage()
{
// 各種オブジェクトの生成と取得
LocalPrintServer lps = new LocalPrintServer();
PrintQueue queue = lps.DefaultPrintQueue;
XpsDocumentWriter writer = PrintQueue.CreateXpsDocumentWriter(queue);
// 用紙サイズの設定
PrintTicket ticket = queue.DefaultPrintTicket;
ticket.PageMediaSize = new PageMediaSize(PageMediaSizeName.ISOA4);
ticket.PageOrientation = PageOrientation.Portrait;
// VisualsToXpsDocumentの生成
VisualsToXpsDocument v2xps = writer.CreateVisualsCollator() as VisualsToXpsDocument;
v2xps.BeginBatchWrite();
try
{
ContainerVisual container = new ContainerVisual();
DrawingVisual dv = new DrawingVisual();
using (DrawingContext dc = dv.RenderOpen())
{
DrawPage(dc);
}
container.Children.Add(dv);
v2xps.Write(container, ticket);
}
finally
{
v2xps.EndBatchWrite();
}
}
印刷処理は、VisualsToXpsDocument.BeginBatchWrite()
から、VisualsToXpsDocument.EndBatchWrite()
の間で行う必要があります。
印刷はページ単位で、VisualsToXpsDocument.Write()
を呼び出すたびに改ページが発生します。