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

投稿で使用できる特殊コードの説明。(別タブで開きます。)
本名は入力しないようにしましょう。
投稿した後で削除するときに使うパスワードです。返答があった後は削除できません。
返答する人が目安にします。相手が小学生か社会人かで返答の仕方も変わります。
最初の投稿が質問の場合、質問者が解決時にチェックしてください。(以降も追加書き込み・返信は可能です。)
※「過去ログ」について書くときはその過去ログのURLも書いてください。

以下の返答は逆順(新しい順)に並んでいます。

投稿者 るきお  (社会人) 投稿日時 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


投稿者 魔界の仮面弁士  (社会人) 投稿日時 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 10:20:15
(削除されました)
投稿者 ろんじ  (社会人) 投稿日時 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にエラーが発生するので、どのような宣言をすればよいでしょうか?