Life is Really Short, Have Your Life!!

ござ先輩の主に技術的なメモ

WPFにおける印刷方法

WPFを帳票フレームワークとして使う - @kotyのブログにあるように、FixDocumentを作ってそこにPageをAddしてXPSに渡すっていう方法がある。これがとユーザーコントロールで帳票をデザイン出来るので、メリットが凄く大きい。

が、実際印刷してみたらかなり重たい。マシンスペックが貧弱だったり、ネットワークでつないでいるプリンタに印刷する場合はストレスになりそうだ・・・。VSからDebug実行しているのが理由であって欲しいが。PageContentに追加しているユーザーコントロールが悪いのか、XPSに流し込む処理はどうしてもメモリを食うのか。もしくはページサイズを設定していないのが問題なのか。ログに吐いてみて、厳密に計測時間を測ってみようと思う。多分Write開始から終わりまでが長い。

var doc = new FixedDocument();
var localPrintServer = new LocalPrintServer();
var printQueue = localPrintServer.GetPrintQueue("プリンタ名");
var xpsDocWriter = PrintQueue.CreateXpsDocumentWriter(printQueue);
for(int i=0;i<3;i++) {
            FixedPage fixedPage = new FixedPage();
            PageContent pageContent = new PageContent();      
            fixedPage.Children.Add(new UserControl());
            ((IAddChild)pageContent).AddChild(fixedPage);
            doc.Pages.Add(pageContent);
}
 xpsDocWriter.Write(doc);

でも他に方法がなさそう・・・。ページ毎にFixedPageは初期化しないといけないから、この方法以外どーしたらいいのかよーわからへん。

2014.08.01 11:18 追記

空のユーザーコントロールを印刷した結果滅茶苦茶早い。。。。

帳票レイアウトにもよるけれども、コレクションをループで回して罫線とデータを1行ずつ描画するような作り方にしてしまうと激重。予めListViewとかですべての描画が終わっているものをXPSで流し込めば実用的な重さかもしれない。

簡単な単票ならこの方式で行けると思いますが、納品書を作るとなると難しいようです。GDIでdrawstringするか、葡萄街のツールを買うか、と。

あと、WPFにおいてXPSでしか印刷出来ないという風潮があるようなのですが、そんなことはありません。単純にSystem.Drawing.Printingで今まで通り印刷できます。こんな感じ。

 PrintObject = new PrintDocument();
 PrintObject.PrintController = new StandardPrintController();
 PrintObject.PrintPage += new PrintPageEventHandler(PrintStart);

 Action<PrintPageEventArgs> DoPrint { get; set; }

  void PrintStart(object sender, PrintPageEventArgs e)
  {
       DoPrint(e);
   }
   void Print() { PrintObject.Print();}

    //delegate実装
  DoPrint = doPrintSomething;
  
  void doPrintSomething(PrintPageEventArgs  e) {
     //drawしていく
  }

おススメはPrintPageハンドラの中でデリゲートできるようActionを仕込んでおくこと。画面ごとに印刷処理を分岐したいときにデリゲートを実装するだけで切り替えられるので。

全然関係ないけど先日この本をみたら、2013年なのに全部Windowsフォームでのアプリの作り方だった。ま、確かに今からWindowsフォームを覚える人もいなくもないのか。すごく丁寧にStep by Stepだったけど、10画面ぐらいあると破綻しそう。

作って覚えるVisual C# 2013 デスクトップアプリ入門

作って覚えるVisual C# 2013 デスクトップアプリ入門

新たに覚えるならWPFのほうがいい。Windowsフォームはもうみたくない。ある程度の行間は埋める必要があるけれど、WPFでのアプリの作り方が解説されている。印刷のところは参考になった。ViewModelを利用してのデータバインディング、コマンド実行、印刷の3つが出来れば生きていける。