印刷のPrintDocument_PrintPageをモジュールに記述したい

タグの編集
投稿者 ろんじ  (社会人) 投稿日時 2021/10/11 09:01:53
VB.netのプログラムについての質問です。よろしくお願いします。
 Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

    ・・・ (内容は割愛します)

PrintDocument1.Print()

EndSub


Private Sub PrintDocument1_PrintPage(sender As Object, e As Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage

    ・・・ (内容は割愛します)

End Sub


このPrintDocument1_PrintPageをフォームのコードエディタではなく、Moduleを新しく作りそこに記述したいです。この場合、Module側にそのまま記述するとPrintDocument1にエラーが発生するので、どのような宣言をすればよいでしょうか?


投稿者 (削除されました)  () 投稿日時 2021/10/11 10:20:15
(削除されました)
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2021/10/11 10:21:54
> Moduleを新しく作りそこに記述したいです。
こういう場合は、「モジュールからフォームを呼ぶ」のではなく、
「フォームからモジュールを呼ぶ」ように設計するのが一般的です。


(案1) Form 側から Module のコードを呼ぶ
Private Sub PrintDocument1_PrintPage(sender As Object, e As Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
    Module1.YourMethod1( e )
End Sub


(案2) Module 側にイベントハンドラを作っておき、それを PrintPage イベントに割り当てる
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    AddHandler Me.PrintDocument1.PrintPage, AddressOf Module1.PrintDocument1_PrintPage
End Sub


(案3) Module 側に PrintPageEventHandler 型のデリゲート インスタンスを用意し、それを PrintPage イベントに割り当てる
※AddressOf を使わないだけで、基本的には案2 と同じ
投稿者 るきお  (社会人) 投稿日時 2021/10/11 20:34:43
ちょっと、ろんじさんのやろうとしていることとは違いますが、私のお勧めは、モジュールではなくクラスを使った次のようなプログラムです。

フォーム上のコントロールのイベントはフォームでハンドルするのがシンプルでわかりやすいので、このプログラムでは、イベント自体はフォームに記述して、イベントの中身はクラスに記述しています。
魔界の仮面弁士さんの案1とほぼ同じです。

フォーム側
Public Class Form1
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        PrintDocument1.Print()
    End Sub

    Private Sub PrintDocument1_PrintPage(sender As Object, e As Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
        Dim report As New MyReport
        report.Draw(e.Graphics)
    End Sub

End Class


クラス側
Public Class MyReport

    Public Sub Draw(g As Graphics)
        Dim rect As New Rectangle(20, 10, 200, 150)
        Dim gradientBrush As New Drawing2D.LinearGradientBrush(rect, Color.Blue, Color.Red, 0)
        g.FillRectangle(gradientBrush, 20, 10, 200, 150)
    End Sub

End Class


どうしてもモジュールでイベントをハンドルしたければ、次のような方法もあります。
(が、上の案の方がお勧めです。)

フォーム側
Public Class Form1
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        PrintDocument1.Print()
    End Sub

    Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles MyBase.Shown
        ReportModule.ReportDocument = Me.PrintDocument1
    End Sub

End Class


モジュール側
Imports System.Drawing.Printing

Public Module ReportModule

    Public WithEvents ReportDocument As PrintDocument

    Private Sub ReportDocument_PrintPage(sender As Object, e As PrintPageEventArgs) Handles ReportDocument.PrintPage
        Dim rect As New Rectangle(20, 10, 200, 150)
        Dim gradientBrush As New Drawing2D.LinearGradientBrush(rect, Color.Blue, Color.Red, 0)
        e.Graphics.FillRectangle(gradientBrush, 20, 10, 200, 150)
    End Sub
End Module