Click to Rate and Give Feedback
MSDN
MSDN Library
Visual Studio 2008
Visual Studio
 How to: Implement Events in Your Cl...

  Switch on low bandwidth view
This page is specific to
Microsoft Visual Studio 2008/.NET Framework 3.5

Other versions are also available for the following:
.NET Framework Developer's Guide
How to: Implement Events in Your Class

Updated: March 2009

The following procedures describe how to implement an event in a class. The first procedure implements an event that does not have associated data; it uses the classes System..::.EventArgs and System..::.EventHandler for the event data and delegate handler. The second procedure implements an event with custom data; it defines custom classes for the event data and the event delegate handler.

NoteNote:

   This topic shows how to declare and raise an event in a class. It does not show how to define an event handler that consumes that event. For information about how to consume events, see Consuming Events and How to: Raise and Consume Events.

For a complete example that illustrates raising and handling events, see How to: Raise and Consume Events.

To implement an event without event-specific data

  1. Define a public event member in your class. Set the type of the event member to a System..::.EventHandler delegate.

    Visual Basic
    Public Class Countdown
        ' ...
    
        Public Event CountdownCompleted As EventHandler
    End Class
    
    
    C#
    public class Countdown 
    {
        // ...
    
        public event EventHandler CountdownCompleted;   
    }
    
    
  2. Provide a protected method in your class that raises the event. Name the method OnEventName. Raise the event within the method. Note that the C# code should check to determine whether the event is null before raising the event. This eliminates the need to handle the NullReferenceException that is thrown when an event is raised but no event handlers have been attached to it. This check is necessary in this case because the CountDown class simply raises the event but does not provide a handler for it.

    Visual Basic
    Public Class Countdown
       ' ...
    
       Public Event CountdownCompleted As EventHandler
    
       Protected Overridable Sub OnCountdownCompleted(e As EventArgs)
          RaiseEvent CountdownCompleted(Me, e)
       End Sub
    End Class
    
    
    C#
    public class Countdown 
    {
        public event EventHandler CountdownCompleted;   
    
        protected virtual void OnCountdownCompleted(EventArgs e)
        {
            if (CountdownCompleted != null)
                CountdownCompleted(this, e);
        }
    }
    
    
  3. Determine when to raise the event in your class. Call OnEventName to raise the event.

    Visual Basic
    Public Class Countdown
       Dim internalCounter As Integer = 0
        ' ...
    
       Public Event CountdownCompleted As EventHandler
    
       Protected Overridable Sub OnCountdownCompleted(e As EventArgs)
          RaiseEvent CountdownCompleted(Me, e)
       End Sub
    
       Public Sub Decrement()
          internalCounter -= 1
          If internalCounter = 0
             OnCountdownCompleted(New EventArgs())
          End If
       End Sub
    End Class
    
    
    C#
    public class Countdown 
    {
       int internalCounter = 0;
       // ...
    
       public event EventHandler CountdownCompleted;   
    
        protected virtual void OnCountdownCompleted(EventArgs e)
        {
            if (CountdownCompleted != null)
                CountdownCompleted(this, e);
        }
    
       public void Decrement()
       {
          internalCounter--;
          if (internalCounter == 0)
             OnCountdownCompleted(new EventArgs());
       }
    }
    
    

To implement an event with event-specific data

  1. Define a class that provides data for the event. Name the class EventNameArgs, derive the class from System..::.EventArgs, and add any event-specific members.

    Visual Basic
    Public Class AlarmEventArgs : Inherits EventArgs
       Private nRings As Integer = 0
       Private pressed As Boolean = False
       Private text As String = "The alarm is ringing!"
    
       ' Constructor.
       Public Sub New(ByVal snoozePressed As Boolean, ByVal nRings As Integer) 
          Me.pressed = snoozePressed
          Me.nRings = nRings
       End Sub
    
       ' Properties.
       Public Property AlarmText() As String
          Get
             Return Me.text
          End Get
          Set
             Me.text = value
          End Set  
       End Property 
    
       Public ReadOnly Property NumRings() As Integer
          Get
             Return Me.nRings
          End Get   
       End Property 
    
       Public ReadOnly Property SnoozePressed() As Boolean
          Get
             Return Me.pressed
          End Get
       End Property
    End Class
    
    
    C#
    public class AlarmEventArgs : EventArgs 
    {
       private readonly int nRings = 0;
       private readonly bool pressed = false;
       private string text = "The alarm is ringing!";
    
       // Constructor.
       public AlarmEventArgs(bool snoozePressed, int nRings) 
       {
          this.pressed = snoozePressed;
          this.nRings = nRings;
       }
    
       // Properties.
       public string AlarmText {  
          get { return text; }
          set { this.text = value; }
       }
    
       public int NumRings {
          get { return nRings; }
       }
    
       public bool SnoozePressed {
          get { return pressed; }
       }
    }
    
    
  2. Declare a delegate for the event. Name the delegate EventNameEventHandler.

    Visual Basic
    Public Delegate Sub AlarmEventHandler(sender As Object, e As AlarmEventArgs)
    
    
    C#
    public delegate void AlarmEventHandler(object sender, AlarmEventArgs e);
    
    
  3. Define a public event member named EventName in your class. Set the type of the event member to the event delegate type.

    Visual Basic
    Public Class AlarmClock
        ' ...
        Public Event Alarm As AlarmEventHandler
    
    End Class
    
    
    C#
    public class AlarmClock 
    {
        // ...
        public event AlarmEventHandler Alarm;
    
    }
    
    
  4. Define a protected method in your class that raises the event. Name the method OnEventName. Raise the event within the method. Note that the C# code should check to determine whether the event is null before raising the event. This eliminates the need to handle the NullReferenceException that is thrown when an event is raised but no event handlers have been attached to it. This check is necessary in this case because the CountDown class simply raises the event but does not provide a handler for it.

    Visual Basic
    Public Class AlarmClock
    
        ' ...
        Public Event Alarm As AlarmEventHandler
    
        Protected Overridable Sub OnAlarm(e As AlarmEventArgs)
            RaiseEvent Alarm(Me, e)
        End Sub
    End Class
    
    
    C#
    public class AlarmClock 
    {
        // ...
        public event AlarmEventHandler Alarm;
    
        protected virtual void OnAlarm(AlarmEventArgs e)
        {
          if (Alarm != null) 
              Alarm(this, e); 
        }
    }
    
    
  5. Determine when to raise the event in your class. Call OnEventName to raise the event and pass in the event-specific data by using EventNameEventArgs.

    Visual Basic
    Public Class AlarmClock
    
        Public Sub Start
            ' ...
            System.Threading.Thread.Sleep(300)
            Dim e As AlarmEventArgs = New AlarmEventArgs(False, 0)
            OnAlarm(e)
        End Sub
    
        Public Event Alarm As AlarmEventHandler
    
        Protected Overridable Sub OnAlarm(e As AlarmEventArgs)
            RaiseEvent Alarm(Me, e)
        End Sub
    End Class
    
    
    C#
    public class AlarmClock 
    {
        public void Start()
        {
            // ...
            System.Threading.Thread.Sleep(300);
            AlarmEventArgs e = new AlarmEventArgs(false, 0);
            OnAlarm(e);
        }
    
        public event AlarmEventHandler Alarm;
    
        protected virtual void OnAlarm(AlarmEventArgs e)
        {
          if (Alarm != null) 
              Alarm(this, e); 
        }
    }
    
    

The following example illustrates how to implement an event with event-specific data. It defines a DiskSpaceMonitor class that uses an event to produce a warning whenever free disk space falls below a percentage defined in a configuration file. It also defines a DiskSpaceWarningEventArgs class to provide custom data on free disk space to event handlers.

Visual Basic
Imports System.Collections.Specialized
Imports System.Configuration
Imports System.IO

Public Class DiskSpaceWarningEventArgs : Inherits EventArgs
   Dim currentFreeSpace As Long
   Dim currentTotalSpace As Long
   Dim driveName As String

   Public Sub New(name As String, freeSpace As Long, totalSpace As Long)
      Me.driveName = name
      Me.currentFreeSpace = freeSpace
      Me.currentTotalSpace = totalSpace
   End Sub

   Public ReadOnly Property Name As String
      Get
         Return Me.driveName
      End Get
   End Property

   Public ReadOnly Property FreeSpace As Long
      Get
         Return Me.currentFreeSpace 
      End Get
   End Property

   Public ReadOnly Property TotalSpace As Long
      Get
         Return Me.currentTotalSpace
      End Get
   End Property
End Class

Public Delegate Sub DiskSpaceWarningEventHandler(sender As Object, _
                                                 e As DiskSpaceWarningEventArgs)

Public Class DiskSpaceMonitor
   Public Event DiskSpaceWarning As DiskSpaceWarningEventHandler
   Private threshold As Decimal 

   Public Sub New()
      ' Retrieve threshold to fire event from configuration file.
      Try
         Dim settings As NameValueCollection = ConfigurationManager.AppSettings
         Me.threshold = CDec(settings.Item("threshold"))
      ' If there is no configuration file, provide a default value.
      Catch e As ConfigurationErrorsException
         Me.threshold = 10d
      Catch e As InvalidCastException
         Me.threshold = 10d
      End Try               
   End Sub

   Public Sub CheckFreeSpace
      ' Get drives present on system.
      Dim drives() As DriveInfo = DriveInfo.GetDrives()
      For Each drive As DriveInfo In drives
         If drive.IsReady Then
            If drive.TotalFreeSpace/drive.TotalSize <= Me.threshold Then
               OnDiskSpaceWarning(New DiskSpaceWarningEventArgs(drive.Name, _
                                  drive.TotalFreeSpace, drive.TotalSize))
            End If
         End If
      Next   
   End Sub

   Protected Sub OnDiskSpaceWarning(e As DiskSpaceWarningEventArgs)
      RaiseEvent DiskSpaceWarning(me, e)
   End Sub
End Class

C#
using System;
using System.Collections.Specialized;
using System.Configuration;
using System.IO;

public class DiskSpaceWarningEventArgs : EventArgs
{
   private long currentFreeSpace;
   private long currentTotalSpace;
   private string driveName;

   public DiskSpaceWarningEventArgs(string name, long freeSpace, long totalSpace)
   {
      this.driveName = name;
      this.currentFreeSpace = freeSpace;
      this.currentTotalSpace = totalSpace;
   }

   public string Name
   {
      get { return this.driveName; }
   }

   public long FreeSpace
   {
      get { return this.currentFreeSpace; }
   }

   public long TotalSpace
   {
      get { return this.currentTotalSpace; }
   }
}

public delegate void DiskSpaceWarningEventHandler(object sender, 
                                                  DiskSpaceWarningEventArgs e);

public class DiskSpaceMonitor
{
   public event DiskSpaceWarningEventHandler DiskSpaceWarning;
   private decimal threshold;

   public void DispSpaceMonitor()
   {
      // Retrieve threshold to fire event from configuration file.
      try
      {
         NameValueCollection settings = ConfigurationManager.AppSettings;
         this.threshold = Convert.ToDecimal(settings["threshold"]);
      }
      // If there is no configuration file, provide a default value.
      catch (ConfigurationErrorsException)
      {
         this.threshold = 10m;
      }
      catch (InvalidCastException)
      {
         this.threshold = 10m;
      }
   }

   public void CheckFreeSpace()
   {
      // Get drives present on system.
      DriveInfo[] drives = DriveInfo.GetDrives();
      foreach (DriveInfo drive in drives)
      {
         if (drive.IsReady)
         {
            if (drive.TotalFreeSpace/drive.TotalSize <= this.threshold)
               OnDiskSpaceWarning(new DiskSpaceWarningEventArgs(drive.Name, 
                                  drive.TotalFreeSpace, drive.TotalSize));
         }
      }
   }

   protected void OnDiskSpaceWarning(DiskSpaceWarningEventArgs e)
   {
      if (DiskSpaceWarning != null)
         DiskSpaceWarning(this, e);
   }   
}

Rather than using the EventArgs class to provide event data, the example defines a custom event data class named DiskSpaceWarningEventArgs. It provides event handlers with the drive name, as well as the amount of free and total space available on the drive. The example also defines a delegate, DiskSpaceWarningEventHandler, that represents the event signature.

The DiskSpaceMonitor class defines the DiskSpaceWarning event and also provides an OnDiskSpaceWarning method that raises the event. The OnDiskSpaceWarning method is in turn called by the CheckFreeSpace method when it detects that the free space available on a drive is less than or equal to a percentage defined in a configuration file.

Date

History

Reason

March 2009

Added additional remarks for the procedures.

Customer feedback.

October 2008

Added an example.

Customer feedback.

Tags What's this?: Add a tag
Community Content   What is Community Content?
Add new content RSS  Annotations
Processing
© 2009 Microsoft Corporation. All rights reserved. Terms of Use  |  Trademarks  |  Privacy Statement
Page view tracker