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.