Thursday, 19 June 2008

.NET events and event handlers

This is a simple description of events and handlers. Does not include custom event arguments.

Child class is the source of the events and Parent class is the sink or consumer of the events. The parent reacts to events originating at the child class.

1. In child class:

A. Declare a delegate defining the signature of event handlers. Parent class functions that handle our events need to implement this delegate. This delegate is required in order to define events in this class.

Example: child class is Car, containing the following delegate:

   1:  public delegate void CarEventHandler(string msg);

B. Declare event names and associate them to the delegate above. These are events this class can send out to subscribers.


   1:  public event CarEventHandler Exploded;
   2:  public event CarEventHandler AboutToBlow;

C. When certain conditions are met, first check event for null and fire it (with same parameters as the delegate - these will be passed on to the handler).


   1:  public void Accelerate(int delta)
   2:  {
   3:      // If the car is dead, fire Exploded event.
   4:      if (carIsDead)
   5:          if (Exploded != null)
   6:              Exploded(this, new CarEventArgs("Sorry, this car is dead..."));
   7:  }

2. In parent class:

A. Define one or more functions implementing the event delegate that will perform the action required when the event fires.


   1:  public static void CarExploded(string msg)
   2:  {
   3:      Console.WriteLine(msg);
   4:  }

B. Create an event handler, associating it with the handling function in the child class, as defined above.

   1:  Car.CarEventHandler carExplodedEventHandler = new Car.CarEventHandler(CarExploded);

C. Register the handler we created with the child class event type we want to handle (usually right after we create this object). If c1 is an object of the type in the child class,

   1:  c1.Exploded += carExplodedEventHandler ;

Now whenever the event fires in the child class, the delegate will execute the CarExploded(string msg) function in the parent class.

   1:  public void Accelerate(int delta)
   2:  {
   3:      // If the car is dead, fire Exploded event.
   4:      if (carIsDead)
   5:      if (Exploded != null)
   6:      Exploded(this,
   7:      new CarEventArgs("Sorry, this car is dead..."));
   8:  }

IMPORTANT NOTE: If you want to refer to a non static function (to fire when the event occurs i.e. function CarExploded in this example) you need to declare it at the class level, but initialise it in the parent class constructor. When declaring the event handler you can declare it readonly. I.e.:

Step 2B becomes:

   1:  readonly Car.CarEventHandler carExplodedEventHandler; // above the constructor

and inside the constructor:

   1:  carExplodedEventHandler = CarExploded;

No comments: