<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://msmvps.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Joacim's view on stuff : event handler, visual basic</title><link>http://msmvps.com/blogs/joacim/archive/tags/event+handler/visual+basic/default.aspx</link><description>Tags: event handler, visual basic</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP2 (Build: 40407.4157)</generator><item><title>Event horizon – Understanding custom events</title><link>http://msmvps.com/blogs/joacim/archive/2009/09/10/event-horizon-understanding-custom-events.aspx</link><pubDate>Thu, 10 Sep 2009 00:36:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1722181</guid><dc:creator>Joacim Andersson</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/joacim/rsscomments.aspx?PostID=1722181</wfw:commentRss><comments>http://msmvps.com/blogs/joacim/archive/2009/09/10/event-horizon-understanding-custom-events.aspx#comments</comments><description>&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In this article I&amp;rsquo;m going to try to explain what custom events are and why you should use them in your code. As you will see the term &lt;em&gt;custom event&lt;/em&gt; in this context is not just an event you have created for your own class, but also a custom way of storing the delegates for this event.&lt;/p&gt;
&lt;p&gt;Most of this article is intended for the VB developer, but with the exception of VB specific parts, especially found in the &lt;em&gt;Background Info &lt;/em&gt;section, the information here also applies to C# (but with a slightly different syntax of course).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Background info&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If you have used VB or any other .Net language for an extended time, you have probably created one or two user controls, or regular classes that raises events. Events in the .Net framework are implemented as properties that accepts a delegate. A delegate is similar to a function pointer in C or C++ although a delegate is strongly typed. I wont dwelve into the difference between a function pointer and a delegate in this article, since that would be an article of its own. Instead I will just simplify and say that a delegate is an address to a method that will be called by the handler (in this case its the object that exposes the event).&lt;/p&gt;
&lt;p&gt;If you want to handle an event raised by an object you can use the &lt;em&gt;AddHandler &lt;/em&gt;statement. But VB also has a simplified solution using the &lt;span style="color:#0000ff;"&gt;Handles&lt;/span&gt; keyword. If you drop a Button on a Form you could then handle its click event like this:&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;Private Sub &lt;/span&gt;Button1_Click(&lt;span style="color:blue;"&gt;ByVal &lt;/span&gt;sender &lt;span style="color:blue;"&gt;As &lt;/span&gt;System.Object, _
                          &lt;span style="color:blue;"&gt;ByVal &lt;/span&gt;e &lt;span style="color:blue;"&gt;As &lt;/span&gt;System.EventArgs) &lt;strong&gt;&lt;em&gt;&lt;span style="color:blue;"&gt;Handles &lt;/span&gt;Button1.Click&lt;/em&gt;&lt;/strong&gt;
  &lt;span style="color:green;"&gt;&amp;#39;code for the click event goes here
&lt;/span&gt;&lt;span style="color:blue;"&gt;End Sub&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The above code will be called when the Click event occur for the object named Button1. This is made possible by another VB specific keyword that&amp;rsquo;s been around since VB5, the &lt;span style="color:#0000ff;"&gt;WithEvents&lt;/span&gt; keyword.&lt;/p&gt;
&lt;p&gt;When you drop the button on the Form the designer will create the code that declares and initializes the component for you. The declaration of the button the designer creates looks like this:&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;Friend WithEvents &lt;/span&gt;Button1 &lt;span style="color:blue;"&gt;As &lt;/span&gt;System.Windows.Forms.Button&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You can use this syntax yourself in your code to handle events raised by objects without the need to call the AddHandler statement. However for clarity I will show the AddHandler approach as well. If the designer wouldn&amp;rsquo;t use the &lt;span style="color:#0000ff;"&gt;WithEvents&lt;/span&gt; keyword, you wouldn&amp;rsquo;t be able to use the &lt;span style="color:#0000ff;"&gt;Handles&lt;/span&gt; keyword either to handle the event.&lt;/p&gt;
&lt;p&gt;&lt;span style="color:blue;"&gt;Friend &lt;/span&gt;Button1 &lt;span style="color:blue;"&gt;As &lt;/span&gt;System.Windows.Forms.Button&lt;/p&gt;
&lt;p&gt;In this case you would need to use the AddHandler in our code.&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;Private Sub &lt;/span&gt;Form1_Load(&lt;span style="color:blue;"&gt;ByVal &lt;/span&gt;sender &lt;span style="color:blue;"&gt;As Object&lt;/span&gt;, _
                       &lt;span style="color:blue;"&gt;ByVal &lt;/span&gt;e &lt;span style="color:blue;"&gt;As &lt;/span&gt;System.EventArgs) &lt;span style="color:blue;"&gt;Handles Me&lt;/span&gt;.Load
  &lt;span style="color:blue;"&gt;AddHandler &lt;/span&gt;Button1.Click, &lt;span style="color:blue;"&gt;AddressOf &lt;/span&gt;Button1_Click
&lt;span style="color:blue;"&gt;End Sub

Private Sub &lt;/span&gt;Button1_Click(&lt;span style="color:blue;"&gt;ByVal &lt;/span&gt;sender &lt;span style="color:blue;"&gt;As &lt;/span&gt;System.Object, _
                          &lt;span style="color:blue;"&gt;ByVal &lt;/span&gt;e &lt;span style="color:blue;"&gt;As &lt;/span&gt;System.EventArgs) &lt;span style="color:green;"&gt;&amp;#39;No Handles keyword
  &amp;#39;code for the click event goes here
&lt;/span&gt;&lt;span style="color:blue;"&gt;End Sub&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;strong&gt;Creating your own events&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s very easy to let your own classes/controls expose events. In most cases you would probably declare your events like this within your class:&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;Public Event &lt;/span&gt;MySpecialEvent(&lt;span style="color:blue;"&gt;ByVal &lt;/span&gt;sender &lt;span style="color:blue;"&gt;As Object&lt;/span&gt;, &lt;span style="color:blue;"&gt;ByVal &lt;/span&gt;e &lt;span style="color:blue;"&gt;As &lt;/span&gt;EventArgs)&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;A class that have the above will expose a &lt;em&gt;MySpecialEvent&lt;/em&gt; event. But this is not enough. It&amp;rsquo;s when you raise the event the code in the event handlers is being executed. So whenever it is time to raise &lt;em&gt;MySpecialEvent&lt;/em&gt; you would use code like this:&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;RaiseEvent &lt;/span&gt;MySpecialEvent(&lt;span style="color:blue;"&gt;Me&lt;/span&gt;, &lt;span style="color:blue;"&gt;New &lt;/span&gt;EventArgs)&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;If you&amp;rsquo;re coming from a VB6 background, this will seem very familiar to you.&lt;/p&gt;
&lt;p&gt;You might call the above a &lt;em&gt;custom event, &lt;/em&gt;since that&amp;rsquo;s what it is. My class has a custom event called &lt;em&gt;MySpecialEvent&lt;/em&gt; which I have implemented using the technique I just demonstrated. But as I mentioned in the introduction section, &lt;em&gt;custom event&lt;/em&gt; (in the lack of a better name) in this context is much more than this. For Custom events you need to keep track of all the event handlers that is used. More about that in the next section.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Custom events = keeping track of event handlers&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;There is a problem with how we created our own events in the previous section: It can become a huge waste of memory resources.&lt;/p&gt;
&lt;p&gt;Let me again take a regular Button in a Windows Forms application as an example. The Button component exposes no less than 68 different events. If they all would be declared with the &lt;em&gt;Public Event EventName&lt;/em&gt; syntax, it would require that 68 fields needs to be created. Lets say a Form contains 10 buttons, that is 680 fields, and in the most likely scenario 670 of these are never used since we&amp;rsquo;re probably only interested in the Click event. So what we end up with are objects that takes longer to instantiate and more usage of heap memory that can&amp;rsquo;t be reclaimed, unless you remove the control from the Form and dispose it (and how often do you do that with controls you&amp;rsquo;ve added to a Form?).&lt;/p&gt;
&lt;p&gt;So if you create your own user control or regular class that exposes many events you need a custom event storage. There is a special collection class called &lt;em&gt;EventHandlerList&lt;/em&gt; in the Framework, available in the System.ComponentModel namespace, which we can use to store the event handlers.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s say I create a class that contains a few typical mouse events and take advantage of the EventHandlerList to store all event handlers, I would write code similar to the following.&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;Public Class &lt;/span&gt;CommonMouseEvents

  &lt;span style="color:blue;"&gt;Private &lt;/span&gt;events &lt;span style="color:blue;"&gt;As New &lt;/span&gt;System.ComponentModel.EventHandlerList
  &lt;span style="color:blue;"&gt;Public Custom Event &lt;/span&gt;Click &lt;span style="color:blue;"&gt;As &lt;/span&gt;EventHandler
    &lt;span style="color:blue;"&gt;AddHandler&lt;/span&gt;(&lt;span style="color:blue;"&gt;ByVal &lt;/span&gt;value &lt;span style="color:blue;"&gt;As &lt;/span&gt;EventHandler)
      events.AddHandler(&lt;span style="color:#a31515;"&gt;&amp;quot;OnClick&amp;quot;&lt;/span&gt;, value)
    &lt;span style="color:blue;"&gt;End AddHandler

    RemoveHandler&lt;/span&gt;(&lt;span style="color:blue;"&gt;ByVal &lt;/span&gt;value &lt;span style="color:blue;"&gt;As &lt;/span&gt;EventHandler)
      events.RemoveHandler(&lt;span style="color:#a31515;"&gt;&amp;quot;OnClick&amp;quot;&lt;/span&gt;, value)
    &lt;span style="color:blue;"&gt;End RemoveHandler

    RaiseEvent&lt;/span&gt;(&lt;span style="color:blue;"&gt;ByVal &lt;/span&gt;sender &lt;span style="color:blue;"&gt;As Object&lt;/span&gt;, &lt;span style="color:blue;"&gt;ByVal &lt;/span&gt;e &lt;span style="color:blue;"&gt;As &lt;/span&gt;System.EventArgs)
      &lt;span style="color:blue;"&gt;Dim &lt;/span&gt;value &lt;span style="color:blue;"&gt;As &lt;/span&gt;EventHandler = &lt;span style="color:blue;"&gt;CType&lt;/span&gt;(events(&lt;span style="color:#a31515;"&gt;&amp;quot;OnClick&amp;quot;&lt;/span&gt;), EventHandler)
      value.Invoke(sender, e)
    &lt;span style="color:blue;"&gt;End RaiseEvent
  End Event

  Public Custom Event &lt;/span&gt;DoubleClick &lt;span style="color:blue;"&gt;As &lt;/span&gt;EventHandler
    &lt;span style="color:blue;"&gt;AddHandler&lt;/span&gt;(&lt;span style="color:blue;"&gt;ByVal &lt;/span&gt;value &lt;span style="color:blue;"&gt;As &lt;/span&gt;EventHandler)
      events.AddHandler(&lt;span style="color:#a31515;"&gt;&amp;quot;OnDblClick&amp;quot;&lt;/span&gt;, value)
    &lt;span style="color:blue;"&gt;End AddHandler

    RemoveHandler&lt;/span&gt;(&lt;span style="color:blue;"&gt;ByVal &lt;/span&gt;value &lt;span style="color:blue;"&gt;As &lt;/span&gt;EventHandler)
      events.RemoveHandler(&lt;span style="color:#a31515;"&gt;&amp;quot;OnDblClick&amp;quot;&lt;/span&gt;, value)
    &lt;span style="color:blue;"&gt;End RemoveHandler

    RaiseEvent&lt;/span&gt;(&lt;span style="color:blue;"&gt;ByVal &lt;/span&gt;sender &lt;span style="color:blue;"&gt;As Object&lt;/span&gt;, &lt;span style="color:blue;"&gt;ByVal &lt;/span&gt;e &lt;span style="color:blue;"&gt;As &lt;/span&gt;System.EventArgs)
      &lt;span style="color:blue;"&gt;Dim &lt;/span&gt;value &lt;span style="color:blue;"&gt;As &lt;/span&gt;EventHandler = &lt;span style="color:blue;"&gt;CType&lt;/span&gt;(events(&lt;span style="color:#a31515;"&gt;&amp;quot;OnDblClick&amp;quot;&lt;/span&gt;), EventHandler)
      &lt;span style="color:blue;"&gt;If &lt;/span&gt;value &lt;span style="color:blue;"&gt;IsNot Nothing Then
        &lt;/span&gt;value.Invoke(sender, e)
      &lt;span style="color:blue;"&gt;End If
    End RaiseEvent
  End Event
  &lt;/span&gt;&lt;span style="color:green;"&gt;&amp;#39;Move event declarations go here...
&lt;/span&gt;&lt;span style="color:blue;"&gt;End Class&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Here we first create an instance of the EventHandlerList class, and then I declare my events.&lt;/p&gt;
&lt;p&gt;Notice the &lt;span style="color:#0000ff;"&gt;Custom&lt;/span&gt; keyword and that the event must be declared as an EventHandler or one of its child classes. Inside the event declaration you must write code for the AddHandler(), RemoveHandler(), and RaiseEvent() procedures (the stub for these are added automatically by the designer in Visual Studio).&lt;/p&gt;
&lt;p&gt;Now, the above is just the declaration of the events and the custom code to store, remove, and invoke the event handlers. You must still raise the events in the normal fashion, using the &lt;em&gt;RaiseEvent&lt;/em&gt; statement.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What exactly are the EventHandlerList?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In the previous section I called the EventHandlerList a collection, but that is not really true. It doesn&amp;rsquo;t implement the IEnumerable interface, it is instead implemented as a linked list. That means that even though we save a great deal of memory space, we might have a trade-off in access speed since we need to search the list from front to end for an event handler. In the case a event handler doesn&amp;rsquo;t exist we need to traverse the whole list.&lt;/p&gt;
&lt;p&gt;So why wasn&amp;rsquo;t this list implemented as a hash table instead? The answer is pretty simple, the list will probably not be very large. Normally you will probably not use more than say 10 events (and in most cases&amp;nbsp;probably&amp;nbsp;less than that) on a given object, and with that small amount of data a linked list is actually much faster than a hash table.&lt;/p&gt;
&lt;p&gt;Have fun!&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fmsmvps.com%2fblogs%2fjoacim%2farchive%2f2009%2f09%2f10%2fevent-horizon-understanding-custom-events.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fmsmvps.com%2fblogs%2fjoacim%2farchive%2f2009%2f09%2f10%2fevent-horizon-understanding-custom-events.aspx" alt="kick it on DotNetKicks.com" border="0" /&gt;&lt;/a&gt;&lt;a rev="vote-for" href="http://pimpthisblog.com/Event-horizon-Understanding-custom-events-Joacims-view-on-stuff"&gt;&lt;img src="http://pimpthisblog.com/image.axd?url=http%3A%2F%2Fmsmvps.com%2Fblogs%2Fjoacim%2Farchive%2F2009%2F09%2F10%2Fevent-horizon-understanding-custom-events.aspx" alt="pimp it" style="border:0px;" /&gt;&lt;/a&gt;&lt;a rev="vote-for" href="http://dotnetshoutout.com/Event-horizon-Understanding-custom-events-Joacims-view-on-stuff"&gt;&lt;img src="http://dotnetshoutout.com/image.axd?url=http%3A%2F%2Fmsmvps.com%2Fblogs%2Fjoacim%2Farchive%2F2009%2F09%2F10%2Fevent-horizon-understanding-custom-events.aspx" alt="Shout it" style="border:0px;" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1722181" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/joacim/archive/tags/vb/default.aspx">vb</category><category domain="http://msmvps.com/blogs/joacim/archive/tags/visual+basic/default.aspx">visual basic</category><category domain="http://msmvps.com/blogs/joacim/archive/tags/custom+events/default.aspx">custom events</category><category domain="http://msmvps.com/blogs/joacim/archive/tags/event+handler/default.aspx">event handler</category><category domain="http://msmvps.com/blogs/joacim/archive/tags/linked+list/default.aspx">linked list</category><category domain="http://msmvps.com/blogs/joacim/archive/tags/events/default.aspx">events</category></item></channel></rss>