C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[4]: PrintPreviewDialogのカスタマイズ


(過去ログ 102 を表示中)

[トピック内 6 記事 (1 - 6 表示)]  << 0 >>

■61081 / inTopicNo.1)  PrintPreviewDialogのカスタマイズ
  
□投稿者/ 五右衛門 (3回)-(2011/08/01(Mon) 16:02:11)

分類:[VB.NET/VB2005 以降] 

(開発言語:VB2008)
PrintPreviewDialogを使って印刷プレビューを表示しようとした時、
PrintPreviewDialog上のプリンタマークのボタンアイコンをクリックすると、
そのままデフォルトのプリンタで印刷を開始してしまいます。
そこで、プリンタマークのアイコンをクリックした時にプリンタの選択ができるように、
以下のサイトを参考にカスタマイズすることができました。
http://winofsql.jp/VA003334/infoboard.php?mid=dnettool&id=080613131401&pid=2

ただし、ここで疑問が生じます。
1.上記サイトでは、以下のようにPrintPreviewDialogのToolStripやそのアイテムをインデックスで指定しています。
  Dim tool As ToolStrip = PrintPreviewDialog1.Controls(1)
  Dim img As System.Drawing.Image = tool.Items(0).Image

  ただし、今後(例えばフレームワークのバージョンが変わった時など)、PrintPreviewDialogのControls(1)が
  ToolStripであるという保証はないでしょうし、ToolStripのItems(0)が印刷ボタンであるという保証もないと思います。
  もっとスマートにToolStripや印刷ボタンを取得する方法はないでしょうか?

2.プリンタの選択と同様の方法で、ページ設定用ボタンもToolStripに追加できると思いますが、
  この場合、ページ設定を行った後にプレビューの内容を更新したいのですが、プレビュー内容の更新はどうすればいいのでしょうか?

アドバイスの程、よろしくお願いします。
引用返信 編集キー/
■61099 / inTopicNo.2)  Re[1]: PrintPreviewDialogのカスタマイズ
□投稿者/ 魔界の仮面弁士 (2281回)-(2011/08/02(Tue) 10:47:09)
2011/08/02(Tue) 12:24:19 編集(投稿者)

No61081 (五右衛門 さん) に返信
> 以下のサイトを参考にカスタマイズすることができました。
undocumented なカスタマイズ手法なので、環境依存なコードになる可能性はありますね。


> 今後(例えばフレームワークのバージョンが変わった時
バージョンポリシーを設定して、バージョンリダイレクトされないようにするとか、
インデックス番号を .exe.config で変更できるようにしておくとか。

もっとも、そういう話をしているわけでは無いのでしょうけれども。


> PrintPreviewDialogのControls(1)が ToolStripであるという保証はないでしょうし、
> ToolStripのItems(0)が印刷ボタンであるという保証もないと思います。
番号指定に抵抗があるのであれば、
 Dim tool = PrintPreviewDialog1.Controls.OfType(Of ToolStrip)().First()
 Dim item = tool.Items.OfType(Of ToolStripButton)().Where(Function(t) t.Text Like "印刷*").First()
という手法もあります。保証が無い点では一緒ですけれどね。


> もっとスマートにToolStripや印刷ボタンを取得する方法はないでしょうか?
それを気にするのであれば、PrintPreviewDialog をカスタマイズするのではなく、
PrintPreviewControl と独自Formを使って、印刷ダイアログを自作するべきかと思いますよ。


> プレビュー内容の更新はどうすればいいのでしょうか?
PrintPreviewControl の InvalidatePreview メソッドを呼び出してみてください。
引用返信 編集キー/
■61111 / inTopicNo.3)  Re[2]: PrintPreviewDialogのカスタマイズ
□投稿者/ 五右衛門 (4回)-(2011/08/02(Tue) 15:09:07)
魔界の仮面弁士様、ご回答ありがとうございました。
No61099 (魔界の仮面弁士 さん) に返信

>>もっとスマートにToolStripや印刷ボタンを取得する方法はないでしょうか?
> それを気にするのであれば、PrintPreviewDialog をカスタマイズするのではなく、
> PrintPreviewControl と独自Formを使って、印刷ダイアログを自作するべきかと思いますよ。

全くおっしゃる通りです。
印刷ボタンは、アイコンではなくて「印刷」と書かれたボタンの方が分かりやすいし、
ページ設定のボタンもヘタなアイコンを使うよりはいいと思っていますので、このさい、
独自プレビューダイアログを作成しようと考えています。

そこで、ついでに質問なのですが、
自作の印刷プレビュー画面では、「次頁」「前頁」またはスピンボタンで表示ページを指定しようと思うのですが、
最大ページ数などはどのように取得すればいいのでしょうか?
PrintDocumentのPrintPageイベントで最大ページ数は分かるのですが、PrintPreviewControlのプロパティなどに
この情報があればいいなと思いまして。

>>プレビュー内容の更新はどうすればいいのでしょうか?
> PrintPreviewControl の InvalidatePreview メソッドを呼び出してみてください。

こちらにつきましては、InvalidatePreviewメソッドを使用することにより解決しました。ありがとうございました。
引用返信 編集キー/
■61120 / inTopicNo.4)  Re[3]: PrintPreviewDialogのカスタマイズ
□投稿者/ 魔界の仮面弁士 (2285回)-(2011/08/02(Tue) 22:20:49)
No61111 (五右衛門 さん) に返信
> PrintDocumentのPrintPageイベントで最大ページ数は分かるのですが、
> PrintPreviewControlのプロパティなどにこの情報があればいいなと思いまして。
取得方法が確立しているのであれば、PrintPreviewControl を継承して、
最大ページプロパティを追加してしまうというのは如何でしょうか。


> 自作の印刷プレビュー画面では、「次頁」「前頁」またはスピンボタンで表示ページを指定しようと思うのですが、
> 最大ページ数などはどのように取得すればいいのでしょうか?

StartPage に Integer.MaxValue を渡すというのはどうでしょうか。

  Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click
      Dim curPage As Integer = PrintPreviewControl1.StartPage
      PrintPreviewControl1.StartPage = Integer.MaxValue
      Dim maxPage As Integer = PrintPreviewControl1.StartPage
      PrintPreviewControl1.StartPage = curPage
      MsgBox(maxPage)
  End Sub



あるいは PreviewPrintController の GetPreviewPageInfo が返す配列の数から
取得できないかな…と思いましたが、こちらは良い手法が思いつきませんでした。

  Private Sub Button2_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button2.Click
      Dim defaultController As System.Drawing.Printing.PrintController
      defaultController = Me.PrintPreviewControl1.Document.PrintController
      Dim sampleController As New Sample()
      Me.PrintPreviewControl1.Document.PrintController = sampleController
      Me.PrintPreviewControl1.Document.Print()
      Dim maxPage As Integer = sampleController.GetCount()
      Me.PrintPreviewControl1.Document.PrintController = defaultController
      MsgBox(maxPage)
  End Sub
  Private Class Sample
      Inherits System.Drawing.Printing.PreviewPrintController
      Public Function GetCount() As Integer
          Dim p() As System.Drawing.Printing.PreviewPageInfo = MyBase.GetPreviewPageInfo()
          Return If(p Is Nothing, -1, p.Length)
      End Function
  End Class

引用返信 編集キー/
■61121 / inTopicNo.5)  Re[4]: PrintPreviewDialogのカスタマイズ
□投稿者/ shu (902回)-(2011/08/02(Tue) 23:21:26)
No61120 (魔界の仮面弁士 さん) の方法に欠点があるのか分からないですが

ちょっと変えてみた。


    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim sampleController As New SampleController()
        MsgBox(sampleController.GetCount(Me.PrintPreviewControl1.Document))
    End Sub


Public Class SampleController
    Inherits System.Drawing.Printing.PreviewPrintController

    Private Pages As Integer

    Public Overrides Sub OnStartPrint(ByVal document As System.Drawing.Printing.PrintDocument, ByVal e As System.Drawing.Printing.PrintEventArgs)
        MyBase.OnStartPrint(document, e)
        Pages = 0
    End Sub

    Public Overrides Sub OnEndPage(ByVal document As System.Drawing.Printing.PrintDocument, ByVal e As System.Drawing.Printing.PrintPageEventArgs)
        MyBase.OnEndPage(document, e)
        Pages += 1
    End Sub

    Public Function GetCount(ByVal doc As PrintDocument) As Integer
        Dim cntlbak = doc.PrintController
        doc.PrintController = Me
        doc.Print()
        doc.PrintController = cntlbak
        Return Pages
    End Function
End Class

引用返信 編集キー/
■61138 / inTopicNo.6)  Re[4]: PrintPreviewDialogのカスタマイズ
□投稿者/ 五右衛門 (5回)-(2011/08/03(Wed) 13:59:10)
2011/08/03(Wed) 13:59:42 編集(投稿者)

(解決チェックつけ忘れ)

魔界の仮面弁士様、shu様、ご回答ありがとうございました。
最大ページの取得は、魔界の仮面弁士様に提示頂いた、PrintPreviewControlのStartPageにInteger.MaxValueを設定して、
StartPageが実際の最終ページに修正されることを利用するのが手っ取り早いので、これを活用しようと思います。
(実際には、StartPageは0から始まるインデックスのようですので、ページ数は+1する必要があります。)

> StartPage に Integer.MaxValue を渡すというのはどうでしょうか。
>
> Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click
> Dim curPage As Integer = PrintPreviewControl1.StartPage
> PrintPreviewControl1.StartPage = Integer.MaxValue
> Dim maxPage As Integer = PrintPreviewControl1.StartPage
> PrintPreviewControl1.StartPage = curPage
> MsgBox(maxPage)
> End Sub

ありがとうございました。これで解決しました。
今後ともよろしくお願い申し上げます。
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -