Microsoft Visual C#で印刷前にプリンタ選択ができるPrintPreviewDialog

.net framework標準のPrintPreviewDialogでは"印刷"実行時にプリンタ選択ができないので、よく使われるのが先にプリンタ選択ダイアログで選択しておいてからプレビューダイアログを表示する方法。

次のようにすれば印刷直前にプリンタ選択ダイアログを表示させ、ソース上もスマートに見えるようになる。


using System.Drawing;
using System.Windows.Forms;

namespace System
{
  /// <summary>
  /// [印刷]ボタンでプリンタ選択できるPrintPreviewDialog
  /// </summary>
  class SelectPrintPreviewDialog : PrintPreviewDialog
  {
    /// <summary>初回読み込み時のみの処理実行フラグ</summary>
    private bool _NewLoad = true;
    /// <summary>印刷終了後のダイアログ自動終了フラグ</summary>
    private bool _CloseFlg = false;

    /// <summary>自動終了実行フラグ</summary>
    public bool AutoClose
    {
        get { return _CloseFlg; }
        set { _CloseFlg = value; }
    }

    /// <summary>
    /// 継承されたコンストラクタ
    /// </summary>
    public SelectPrintPreviewDialog()
    {
    }

    /// <summary>
    /// 継承されたOnLoadイベント
    /// </summary>
    protected override void OnLoad(EventArgs e)
    {
        if (_NewLoad)
        {
            ToolStrip tool = this.Controls[1] as ToolStrip;
            ToolStripButton tbtn = new ToolStripButton();
            ToolStripSeparator tsep = new ToolStripSeparator();

            tbtn.Image = tool.Items[0].Image.Clone() as Image;
            tbtn.ToolTipText = tool.Items[0].ToolTipText;
            tbtn.Click += new EventHandler(printerselectAndPrint);

            // [印刷]ボタンを差し替える(一緒に区切り線も挿入)
            tool.Items.RemoveAt(0);
            tool.Items.Insert(0, tbtn);
            tool.Items.Insert(1, tsep);

            _NewLoad = false;
        }

        base.OnLoad(e);
    }

    /// <summary>
    /// 印刷実行前にプリンタ選択ダイアログを表示するイベント
    /// </summary>
    private void printerselectAndPrint(object sender, EventArgs e)
    {
        if (this.Document == null)
        {
            return;
        }

        using (PrintDialog prtDlg = new PrintDialog())
        {
            // XP Styleを有効に(Windows 2000以前だと無視される)
            prtDlg.UseEXDialog = true;
            // プレビューの印刷設定をダイアログに渡す
            prtDlg.Document = this.Document;

            if (prtDlg.ShowDialog() == DialogResult.OK)
            {
                // ダイアログで変更された設定を書き戻す
                this.Document = prtDlg.Document;

                // 印刷実行
                this.Document.Print();

                // 自動終了が有効ならダイアログを終了する
                if (_CloseFlg)
                {
                    this.Close();
                }
            }
        }
    }
  }
}

実際に使用する時には以下のような使用方法となる。


  PrintDocument pDoc = new PrintDocument();

  // (ここに印刷オブジェクト生成処理を書く)

  using (SelectPrintPreviewDialog prtDlg = new SelectPrintPreviewDialog())
  {
    prtDlg.Document = pDoc;
    prtDlg.AutoClose = true;

    prtDlg.ShowDialog();
  }

このサンプルではnamespaceをSystemにしているが、独自クラスに纏めてDLLにしておくのも便利。

今回のように、継承は上手く使うとイベントの差し替え等は簡単にできる。表示系の変更はLoad、もしくはShow(オブジェクトの生成位置による)で1回だけ行うこと。

[ 戻る ]