473,834 Members | 1,884 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

How To: Use Events In .NET

9,735 Recognized Expert Moderator Expert
An Event is a message sent out by an object to notify other objects that an action/trigger/state-change (ie. an event) has taken place. Therefore, you should use an event when an object's state change requires other objects to change as well.

The object that sends an event is known as the event sender.
The object that receives (or listens for) the event is known as the event receiver.

Events implement the "Observer Design Pattern". This pattern contains two key objects: a subject (the event sender), and an observer (the event receiver). The subject may have one or many observers.

Delegates are used in order to communicate between the sender and the receiver objects since the sender does not know what object type may be receiving (or handling) the event. The Delegate connects the Event with it's receiver (or handler).

Recall that, in .NET, Delegates are classes that serve as function pointers. They hold a reference (memory location) to a method. Also remember that Delegates can only hold references to methods that match its signature.

The Delegate identifies the method that provides the response to the event and holds the event data.

Using Generic Events (EventHandler Delegate)

A generic event handler delegate has been made available in the.NET Framework 2.0. It's referred to as EventHandler.

The EventHandler delegate holds a reference to a method that handles events raised which do not contain event data. In other words, it represents the method that will handle a typical event.

The EventHandler delegate's signature is as follows:
Expand|Select|Wrap|Line Numbers
  1. Public Delegate Sub EventHandler(ByVal sender As Object, ByVal e As EventArgs)
Expand|Select|Wrap|Line Numbers
  1. public delegate void EventHandler(Object sender, EventArgs e)
  • The "sender" parameter is the object raising the event.
  • The "e" parameter is the event arguments that are passed back to the receiving object and contain data about the event. Since the event doesn't generate event data, this parameter is an instance of EventArgs.
  • If you require the event to generate event data (data that can be used by the receiving object in order to process something), then you cannot use the EventHandler. Instead you must use the EventHandler<T> . This is explained in more detail in the next section.

So if you needed to raise an event that does not generate event data you would declare your event as:
Expand|Select|Wrap|Line Numbers
  1.     Public Event NoDataEventHandler As EventHandler
  2.     'EventHandler is the delegate that holds a reference to a method with the signature: (Object sender, EventArgs e)
  3.     'You do not need to create a delegate called EventHandler as this is now part of the System class
Then to raise the event in your sender class would do the following:
Expand|Select|Wrap|Line Numbers
  1. Private Sub OnMyEvent()
  2.    RaiseEvent NoDataEventHandler(Me, New EventArgs())
  3. End Sub

Using Events That Return Event Data (EventHandler<T > Delegate)
If, when you raise the event, you need to pass data to the receiving objects, you cannot use the EventHandler delegate. Instead you need to use EventHandler<T> .

Since your event generates event data, you must first create a custom type to hold this data. This custom type has to be derived from EventArgs.
Expand|Select|Wrap|Line Numbers
  1. Public Class MyObjectsEventArgs
  2.      Inherits EventArgs
  3.      Private _theEventData As String
  4.      Public Sub New(ByVal eventData As String)
  5.           _theEventData = eventData
  6. End Sub
  7. Public Property Message() As String
  8.         Get
  9.             Return _theEventData
  10.         End Get
  11.         Set(ByVal value As String)
  12.             _theEventData = value
  13.         End Set
  14.     End Property
  15. End Class
Now, because you cannot use the generic EventHandler, you need to create a Delegate using the EventHandler<T> delegate instead:
Expand|Select|Wrap|Line Numbers
  1.      Public Delegate Sub XEventHandler(Of MyObjectsEventArgs)(ByVal sender as Object, ByVal e As MyObjectsEventArgs)
  2.     'Note that MyObjectsEventArgs is the custom type derived from EventArgs used to pass the event data to the receiving class.
Remember that you have to declare Delegates out side of your Class that raises the event. Also, note that this is a Public Delegate. It needs to be Public in order for the receiving object to be able to access it.

If you declare you Delegate as:
Expand|Select|Wrap|Line Numbers
  1.      Public Delegate Sub XEventHandler(ByVal sender as Object, ByVal e As MyObjectsEventArgs)
  2.      'Note that MyObjectsEventArgs is the custom type derived from EventArgs used to pass the event data to the receiving class.
You will receive a warning from the compiler (run using code analysis):
... generates EventHandler delegates for events that use the following pattern: Event MyEvent(ByVal Sender As Object, ByVal e As MyEventArgs). Change the event that defines EventHandler 'EventHandler' to use EventHandler<T> ..."
It is complaining that you are declaring a Delegate that uses the EventHandler's signature except that you are not using EventArgs in the signature.
Now that you have a delegate to use to link the sender and receiver classes, you can declare an event as:
Expand|Select|Wrap|Line Numbers
  1.      Public Event SendMessageEvent As XEventHandler(Of MyObjectsEventArgs)
Remember that you declare your event inside of your sender class. It should also be made public for the receiver class to handle.

To raise the event in your sender code you would do the following:
Expand|Select|Wrap|Line Numbers
  1. Private Sub OnMyEvent(ByVal message As String)
  2.      RaiseEvent SendMessageEvent(Me, New MyObjectsEventArgs(message))
  3. End Sub
In your Receiving Class you need to create a method that matches the signature of the delegate in order to handle the event:
Expand|Select|Wrap|Line Numbers
  1. Private Sub TestEventSending_theEvent(ByVal sender As Object, ByVal e As MyObjectsEventArgs) Handles TestEventSending.SendMessageEvent 
  2.     'Note that "TestEventSending" is the instance of the Sender Object used in my Receiving Object
  3.     Label_Message = e.Message
  4.     'e is an instance of the MyObjectsEventArgs class we implemented to be able to send event data to the receiving object for it to use
  5.     'Recall that Message is a property of MyObjectsEventArgs that we defined to hold our event data
  6. End Sub
References and Resources
EventHandler Generic Delegate
EventHandler(TE ventArgs) Generic Delegate
Jan 17 '08 #1
3 9504
7,872 Recognized Expert Expert
I am not sure how this applies in VB.NET, but I know how to handle it in C#.

If you have a custom event in your class called say "MyEvent", if you trigger that event without an event handler attached, an exception is thrown. BUT, you can check for null on the event first to know if it is safe to fire the event.

Expand|Select|Wrap|Line Numbers
  1. public delegate void NotifyStatusHandler(string Status);
  3. public class MyClass
  4. {
  5.    public event NotifyStatusHandler NotifyStatus;
  6.    private void _NotifyStatus(string Status)
  7.    {
  8.       if (NotifyStatus != null)
  9.       {
  10.          NotifyStatus(Status);
  11.       }
  12.    }
  13.    public void TriggerEvent()
  14.    {
  15.       _NotifyStatus("testing");
  16.    }
  17. }
Instead of calling the event directly to trigger it, I call a private function that checks to see if there is a delegate attached first or not
Nov 11 '08 #2
229 Recognized Expert New Member
Good practice would also be to assign the event handler to a local, temporary variable before checking if it is null. This way you can avoid an exception in case some other thread unsubscribes from the handler just after you have checked it.

Expand|Select|Wrap|Line Numbers
  1.     private void _NotifyStatus(string Status)
  2.     {
  3.         // get a local reference
  4.         NotifyStatusHandler handler = NotifyStatus;
  6.         if (handler != null)
  7.         {
  8.             // even if NotifyStatus is null in this moment,
  9.             // we are sure that 'handler' is non-null
  10.             handler (Status);
  11.         }
  12.     }
Feb 17 '09 #3
6 New Member
If we call Delegate.Invoke () then the handler will get called synchronously. Means till the handler function is completed the control will not return back.

Expand|Select|Wrap|Line Numbers
  1. delegate void Foo();
  3. Foo evtFoo;
  5. evtFoo.Invoke(); //This will not return until the associated handler function is completed
In order to call it async, use BeginInvoke(). This function is coupled with EndInvoke(). EndInvoke() will wait till the handler operation is completed. In case you do not want to use EndInvoke() then BeginInvoke() accepts one parameter as function callback. This function will get called once the handler operation is completed.

Expand|Select|Wrap|Line Numbers
  1. evtFoo.BeginInvoke(MyCallback, null);
MyCallback should have a signature like this

Expand|Select|Wrap|Line Numbers
  1. void MyCallback(IAsynResult ar);
Oct 30 '09 #4

Sign in to post your reply or Sign up for a free account.

Similar topics

by: Sasha | last post by:
Hi everyone, Here is my problem: I have the following classes: - DataNode - this class is designed to hold some data and will be contained in a tree like data structure DataTree. When DataNode is changed, it raises "Changed" event. The class has a reference to the DataNode it is being contained in: - DataTree - tree like data structure that contains DataNodes; When
by: Saso Zagoranski | last post by:
Hi! How can I unregister all the events registered to a control? I have seen a piece of code in another thread, which gets all the registered handlers for a specific event. Let's say I have a CustomTextBox : TextBox, which has quite a lot of events... Do I put unregistering code for all the possible events in the Dispose method? Or is there another way?
by: JPRoot | last post by:
Hi I use the following syntax to have events inherited from base to child classes which works nicely (virtual and override keyword on events). But I am wondering if it is a "supported" way of using events since I never saw it used anywhere in MSDN documentation/samples?! Or it will just break when I upgrade to .NET Framework 2.x in the coming years namespace MyNamespac public delegate void MyDel() public class MyBase public virtual...
by: Bob Rundle | last post by:
I have the following code, which appears to be working. However it doesn't look right. The part I am wondering about is the logic in DisconnectEvents(). This logic creates a new delegate and then expects to find that delegate in the list of event handlers. What is the proper way of writing this? Regards, Bob Rundle
by: LP | last post by:
Hello! I am still transitioning from VB.NET to C#. I undertand the basic concepts of Delegates, more so of Events and somewhat understand AsyncCallback methods. But I need some clarification on when to use one over another? If anyone could provide any additional info, your comments, best practices, any good articles, specific examples, etc. Thank you
by: Nicky Smith | last post by:
Hello, I'm studying a book on VB.net Win apps, and I'm reading a section on events and delegates and raising events. Is it just me, or is this not just subs dressed up as something else? I mean, for one, delegates point to subs, so when you call a delegate, why not just call the sub dierectly and not bother adding the extra code involved adding the delegate?
by: Burkhard | last post by:
Hi, I am new to C# (with long year experience in C++) and I am a bit confused by the language construct of events. What is it I can do with events that I cannot do with delegates? At the moment it seems to me that Microsoft has developed similar functionality via two keywords. I do understand that an event offers better encapsulation as the underlying delegate is private, but is that all ? -- Regards
by: Richard Maher | last post by:
Hi, Here I mean "User" in the Programmer or Javascript sense. I merely wish to programmatically trigger an Event. It would be absolutely fantastic if there was a (Form level?) ONUSEREVENT() and a setEvent() function but, in the absence of this, is it not possible to use DOM to change an object's properties resulting in a state-change event? I have tried with ONCHANGE() and that only seems to work if the "interactive" user changes the...
by: xoozlez | last post by:
Hi there, I have a registration form where I like to filter out the past events of 2007. This is the code I am using : strSQL = "SELECT EventID, EventName, EventDateBegin, EventDateEnd, EventTimeBegin, Category FROM Events WHERE EventDateBegin >'01/01/2008' AND Events.Category LIKE '3' OR Events.Category LIKE '4' OR Events.Category LIKE '5' OR Events.Category LIKE '6' OR Events.Category LIKE '7' OR Events.Category LIKE '8' OR...
by: swethak | last post by:
Hi, I am desiging the calendar application for that purpose i used the below code. But it is for only displys calendar. And also i want to add the events to calendar. In that code displys the events when click on that date that perticular event displyed in a text box.But my requirement is to when click on that date that related event displyed in same td row not the text box. and also i add the events to that calendar.plz advice how to...
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.