简体   繁体   中英

How to raise an event across classes and module

I have a WinForms class that presents a TreeView of some network nodes. I have a separate module that interfaces with the network and detects when nodes are added or removed. I would like the module to trigger the TreeView when the network changes.

Example

Public Class Main

     Friend Sub TV_Main_Network_Click ( ByVal sender As System.Object,  _
         ByVal e As System.EventArgs) _
         Handles TV_Main_Network.Enter, TV_Main_Network.Click

     End Sub

End Class

Module Monitor

    Friend Sub Test()
        TV_Main_Network_Click()
    End Sub

End Module

There are two problems:

  1. Error: Name " TV_Main_Network_Click " is not declared
  2. What parameters would one pass - these are unused, but must exist

I also tried

RaiseEvent TV_Main_Network.Click

but this gives the error:

TV_Main_Network_Click is not an event of .Monitor

I would handle this by creating a public event in the module:

Public Event ChangeOccured(<variables to let the node class know what is going on>)

then when declaring the node class you should pass the network object to it byref and add a handler in the new function:

AddHandler NetworkModule.ChangeOccured, Addressof HandlingFunction

You'll of course need to create the function as such:

Private Sub HandlingFunction(<same params as in the ChangeOccured event declaration>)
    <code>
End Sub

~~~~~~~~~~~~~~~~~~~~~~~~~Edit 1~~~~~~~~~~~~~~~~~~~~~~~~~~~

If your file system watcher module isn't a class yet, I would consider making it one.

~~~~~~~~~~~~~~~~~~~~~~~~~Edit 2: 11/23/2009 3:30 PM~~~~~~~~~~~~~~~~~~~~~~~~~~~

There are four steps to creating and using a custom event in .NET which I've displayed above. I will break them down for you here:

Step 1: Declare the custom event in your class so that other code can latch onto it and create handlers for it.

Public Event ChangeOccured(<variables to let the node class know what is going on>)

Step 2: Actually make your class raise the event so that anything that is attached to it gets fired.

RaiseEvent ChangeOccured(<variables of the same type declared in step 1 go here>)

Step 3: Create a function outside the class (wherever you need it) that needs to be called when an event fires.

Private Sub HandlingFunction(<same params as in the ChangeOccured event declaration>)
    <code>
End Sub

Step 4: Attach the function to the event that will happen when it gets raised from other classes. You do this on formload or after the class is instantiated.

AddHandler NetworkModule.ChangeOccured, Addressof HandlingFunction

Its really a simple process after you understand what exactly it does. Once you understand those four steps, you begin to realize that all of .NET form objects are actually written this way and that there are really a lot of tricks you can do with event handlers and form objects that you couldn't do otherwise.

Ok, the other answer was right but jargonish. So if you want to a event to be received across classes here is what you do.

Example: You have a form class with a button that starts a custom timer class. You want the form class to pick up every tick event that happens within this class...

So for the form class it would look something like this.

Public Class FRM_TIMETICK

Dim TIMER_INSTANCE As New TIMETICK 'SPECIALTY TIMER CLASS INSTANCE.

Private Sub BTN_START_TIMER_Click(sender As Object, e As EventArgs) Handles BTN_START_TIMER.Click
    TIMER_INSTANCE.START_TIMER(2000) 'FUNCTION WITHIN THE CLASS THAT STARTS THE TIMER.
    AddHandler TIMER_INSTANCE.TICK, AddressOf TICK 'ADD A HANDLER TO PICK UP ON THE TICK EVENTS INSIDE THE CLASS,
    'THE "AddressOf TICK" DIRECTS THE HANDLER TO THE FUNCTION/SUB TO EXECUTE.
End Sub

Private Sub TICK()
    'CODE TO EXECUTE ON EACH TIMER TICK.
End Sub

And then in the class where the event is happening...

Public Class TIMETICK

Dim TIMER As New Timers.Timer 'THE TIMER TO BE DETECTED BY THE OUTSIDE CLASS.

Public Event TICK()

Public Function START_TIMER(ByVal INTERVAL_mS As UInteger, Optional ByVal AUTO_RESET As Boolean = True) As Boolean
    With TIMER
        .Interval = INTERVAL_mS
        'SET THE INTERVAL IN MILLISECONDS.
        .AutoReset = AUTO_RESET
        '^TRUE MAKES THE TIMER LOOP INDEFINITLY, FALSE WONT LOOP.
        .Enabled = True
        '^ENABLE THE CONTROL.
        AddHandler .Elapsed, New ElapsedEventHandler(AddressOf TIMER_TICK)
        '^CREATE A HANDLE FOR EVERY TICK OF THE TIMER.
        .Start()
    End With
    Return True
End Function

Private Sub TIMER_TICK(SENDER As Object, E As ElapsedEventArgs)
    RaiseEvent TICK()
End Sub

Hope this helps anyone else that stumbles across this.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM