かずきのBlog@hatena

すきな言語は C# + XAML の組み合わせ。Azure Functions も好き。最近は Go 言語勉強中。日本マイクロソフトで働いていますが、ここに書いていることは個人的なメモなので会社の公式見解ではありません。

UWPで印刷

基本的にWindows 8系の頃と変わってません。

OnNavigatedToで印刷系各種準備を行います。一見無意味に見えるPrintDocumentSourceの取得も意味があるので写経しましょう。

private PrintDocument printDocument;
private IPrintDocumentSource printDocumentSource;

public MainPage()
{
    this.InitializeComponent();
}

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    base.OnNavigatedTo(e);

    this.printDocument = new PrintDocument();
    this.printDocumentSource = this.printDocument.DocumentSource;
    this.printDocument.GetPreviewPage += this.PrintDocument_GetPreviewPage;
    this.printDocument.Paginate += this.PrintDocument_Paginate;
    this.printDocument.AddPages += this.printDocument_AddPages;

    PrintManager.GetForCurrentView().PrintTaskRequested += this.MainPage_PrintTaskRequested;
}

GetPreviewPageがプレビューページの表示処理で、Paginateが、ページの中身を作る処理とページ数を確定するところで、AddPagesが印刷する表示を持ったUIElementを実際に印刷処理に渡すところです。そして、PrintTaskRequestedイベントハンドラを登録して印刷の準備完了です。

各種イベントハンドラの中身は以下のような感じになります。画面にImageという名前のImageコントロールを置いていて、それを印刷するコードになっています。

private void printDocument_AddPages(object sender, AddPagesEventArgs e)
{
    // 印刷(複数ページあるときはAddPageを複数回呼ぶ)
    this.printDocument.AddPage(this.Image);
    this.printDocument.AddPagesComplete();
}

private void PrintDocument_Paginate(object sender, PaginateEventArgs e)
{
    // ここで印刷コンテンツを作ってページ数を設定する
    this.printDocument.SetPreviewPageCount(1, PreviewPageCountType.Intermediate);
}

private void PrintDocument_GetPreviewPage(object sender, GetPreviewPageEventArgs e)
{
    // プレビューを表示する
    this.printDocument.SetPreviewPage(e.PageNumber, this.Image);
}

private void MainPage_PrintTaskRequested(PrintManager sender, PrintTaskRequestedEventArgs args)
{
    // プリントのタスクを登録する
    args.Request.CreatePrintTask("Sample", req =>
    {
        req.SetSource(this.printDocumentSource);
    });
}

最後にボタンのクリックとかで印刷のUIを呼び出しましょう。

private async void Button_Click(object sender, RoutedEventArgs e)
{
    await PrintManager.ShowPrintUIAsync();
}

これで印刷プレビューが表示されて実際に印刷がされます。

複数ページあるようなアプリでは、別画面に行くときとかにプリンタとの接続を切っておきます。

protected override void OnNavigatedFrom(NavigationEventArgs e)
{
    base.OnNavigatedFrom(e);

    PrintManager.GetForCurrentView().PrintTaskRequested -= this.MainPage_PrintTaskRequested;
}