C# Standard Event Pattern

Description

The .NET Framework defines a standard pattern for writing events.

Step 1

System.EventArgs is a predefined Framework class with no members. EventArgs is a base class for conveying information for an event.

We can subclass EventArgs to convey the old and new values when a ValueChanged event is fired:


public class ValueChangedEventArgs : System.EventArgs
{/*  w  w w . ja  v  a  2  s .  c  o  m*/
 public readonly decimal LastValue;
 public readonly decimal NewValue;


 public ValueChangedEventArgs (decimal lastValue, decimal newValue)
 {
   LastValue = lastValue;
   NewValue = newValue;
 }
}

It typically exposes data as properties or as read-only fields.

Step 2

With an EventArgs subclass in place, the next step is to choose or define a delegate for the event.

The Framework defines a generic delegate called System.EventHandler<> we can use.


public class Rectangle
{/*from   w ww.j a v  a 2 s  .c o m*/
   ...
   public event EventHandler<ValueChangedEventArgs> ValueChanged;
}

Step 3

You write a protected virtual method that fires the event.

The name must match the name of the event, prefixed with the word On, and then accept a single EventArgs argument:


/*w w  w .jav a2s. com*/
public class Rectangle {
  public event EventHandler<ValueChangedEventArgs> ValueChanged;

  protected virtual void OnValueChanged (ValueChangedEventArgs e)
  {
    if (ValueChanged != null) ValueChanged (this, e);
  }
}

This provides a central point from which subclasses can invoke or override the event.

Example

Here's the complete example:


using System;                                                                                    
public class ValueChangedEventArgs : EventArgs
{//w w  w .j a  v  a 2s  .c  om
  public readonly decimal LastValue;
  public readonly decimal NewValue;

  public ValueChangedEventArgs (decimal lastValue, decimal newValue)
  {
    LastValue = lastValue; NewValue = newValue;
  }
}

public class Rectangle
{
  string symbol;
  decimal myValue;

  public Rectangle (string symbol) {this.symbol = symbol;}

  public event EventHandler<ValueChangedEventArgs> ValueChanged;

  protected virtual void OnValueChanged (ValueChangedEventArgs e)
  {
    if (ValueChanged != null) ValueChanged (this, e);
  }

  public decimal MyWidth
  {
    get { return myValue; }
    set
    {
      if (myValue == value) return;
      OnValueChanged (new ValueChangedEventArgs (myValue, value));
      myValue = value;
    }
  }
 }

class Test
{
  static void Main()
  {
    Rectangle stock = new Rectangle ("A");
    stock.MyWidth = 2;
    stock.ValueChanged += stock_ValueChanged;
    stock.MyWidth = 3;
  }

  static void stock_ValueChanged (object sender, ValueChangedEventArgs e)
  {
    Console.WriteLine (e.NewValue);
    Console.WriteLine (e.LastValue);
  }
 }

The code above generates the following result.





















Home »
  C# Tutorial »
    Custom Types »




C# Class
C# Struct
C# Interface
C# Inheritance
C# Namespace
C# Object
C# Delegate
C# Lambda
C# Event
C# Enum
C# Attribute
C# Generics
C# Preprocessor