読者です 読者をやめる 読者になる 読者になる

いろいろ備忘録日記

主に .NET と Python絡みのメモを公開しています。

WithEventsおよび手動イベント登録のサンプル

最近、VisualBasic2005を触る機会が多いのですが、イベント周りの書き方をよく忘れてしまうので
それのメモです。(どうしても、C#の書き方で書いてしまってコンパイルエラーが多いです・・・w)


C#の場合、以下のようにイベント用のdelegateとイベント用のArgsクラスを作成して
イベントを公開するクラスにて、イベントを公開します。

public delegate void XXXXHandler(object sender, XXXXEventArgs e);

public class XXXXEventArgs : EventArgs{
    //
    // 処理は、割愛します。
    //
}

public class EventTest{
    
    public event XXXXHandler XXXXEvent;
}

で、イベントを以下のようにして登録します。

EventTest t  = new EventTest();
t.XXXXEvent += XXXXHandler(HogeMethod);


同じことをVB2005で行なう場合、WithEventsを使う場合とAddHandlerを使って登録する場合の2つのやり方があります。
まずは、WithEventsを使う場合。
イベントを持つクラスを別のクラスのフィールドとして宣言する際にWithEventsをつけると、コールバックメソッドを
記述するだけでそのクラスの該当イベントに登録させることが出来ます。
実際に見た方がわかりやすいと思います。

Public Delegate Sub XXXXHandler(ByVal sender As Object, ByVal e As XXXXEventArgs)

Public Class XXXXEventArgs
    Inherits EventArgs
    '
    ' 処理は割愛します。
    '
End Class

Public Class EventTest
    
    Public Event XXXXEvent as XXXXHandler

End Class

イベントを登録するクラスです。

Module EntryPoint
    '
    ' WithEvents付きで宣言
    '
    Private WithEvents _t as EventTest

    '
    ' コールバックの宣言
    '
    Private Sub MyCallback(ByVal sender As Object, ByVal e As XXXXEventArgs) Handles _t.XXXXEvent
    End Sub
End Module

上記の場合、C#で行なっていた

t.XXXXEvent += XXXXHandler(HogeMethod);

の部分が

    Private Sub MyCallback(ByVal sender As Object, ByVal e As XXXXEventArgs) Handles _t.XXXXEvent

で、自動的に行なわれています。
AddHandlerの場合は自動登録を行なわず、手動でイベントを登録する際に使用します。


以下、WithEventsとAddHandlerのサンプルです。

Public Delegate Sub MyCallbackHandler(ByVal sender As Object, ByVal e As MyCallbackEventArgs)

Public Class MyCallbackEventArgs
    Inherits EventArgs

    Private _state As String

    Public Sub New(ByVal userState As String)
        _state = userState
    End Sub

    Public ReadOnly Property State() As String
        Get
            Return _state
        End Get
    End Property

End Class

Public Class WithEventTest

    ''' 
    ''' サンプルイベントです。
    ''' 
    ''' 
    ''' 特にありません。
    ''' 
    Public Event MyCallbackEvent As MyCallbackHandler

    Public Sub Execute()
        '
        ' イベントを発行します。
        ' 
        ' イベントを発行するには、RaiseEvent イベント名と記述します。
        '
        RaiseEvent MyCallbackEvent(Me, New MyCallbackEventArgs("イベントが発行されました"))
    End Sub
End Class

Module EntryPoint

    '
    ' WithEvent付きでメンバを宣言します。
    '
    Private WithEvents _test As WithEventTest

    ''' 
    ''' MyCallbackEvent用のコールバックメソッドです。
    ''' 
    ''' イベント発生元オブジェクト
    ''' イベント引数オブジェクト
    ''' 
    ''' 特にありません。
    ''' 
    Private Sub CallbackMethod(ByVal sender As Object, ByVal e As MyCallbackEventArgs) Handles _test.MyCallbackEvent
        Console.WriteLine(e.State)
    End Sub

    Sub Main()
        '
        ' (1) WithEvents付きでイベントを登録して実行してみます。
        '
        _test = New WithEventTest()

        _test.Execute()

        '
        ' (2) WithEvents無しでイベントを手動で登録して実行してみます。
        '
        ' WithEvent無しの場合は、以下の記述でイベントを登録します。
        '       AddHandler xxx.EventName, AddressOf コールバックメソッド
        '
        Dim _test2 As WithEventTest = New WithEventTest()

        '
        ' イベントを登録します。
        '
        AddHandler _test2.MyCallbackEvent, AddressOf CallbackMethod

        _test2.Execute()

    End Sub
End Module