Introduction
This article provides a very brief introduction to writing custom event generators (and handlers). The article is aimed at people new to the language but with perhaps some prior knowledge in other programming languages. This article does not cover the topic in detail, a resource for this would be C# Event Implementation Fundamentals, Best Practices and Conventions.
Background
An event is defined in C# as 'a member that enables an object or class to provide notifications', i.e. the event notification system provides linking to allow sections of code to be run in response to certain actions occurring, typically user interface (UI) actions such as button clicks.
Delegates are essentially interfaces to methods, and allow methods to be passed as parameters. For a more detailed introduction to delegates see Delegates And Events - The Uncensored Story. To create a delegate for a method(s) the delegate must match exactly the input and output type parameters (but not neccaserily name), e.g.;
public delegate void SomeDelegate(String name);
public void okMethod(String s) {
Console.WriteLine(s);
}
public bool badMethod(String s) {
return s.Length > 4;
}
okMethod
may be encapsulated via new SomeDelegate(okMethod)
as both the input types and output type match, however badMethod
cannot due to a non-matching return value.
Using the code
Custom Event handling requires 3 classes, a generator, a custom parameter encapsulation, and something to catch the event (or depending on the circumstances many catching classes). In the provided sample code the generator class is EventGenerator
, the custom parameter encapsulation is MyEventArgs
, and the catcher is EventCatcher
. Additionally Program
creates the generator and catcher objects and links them.
MyEventArgs - Custom Parameter Encapsulation
public class MyEventArgs : EventArgs
{
public delegate void MyHandler(object sender, MyEventArgs e);
public String someArg;
public int moreArgs1;
public double moreArgs2;
}
MyEventArgs
extends EventArgs
to allow the event subsystem to process it as an event parameter. someArg
, moreArgs1
, and moreArgs2
store the custom parameters to be passed from the generator to the catching handlers, this should be tailored to the specific task; for common UI tasks many EventArgs
exist, such as MouseEventArgs
and MouseButtonEventArgs
. The delegate
MyHandler
defines the structure of handler methods for the custom event; note, it is not essential to specify a sender
however it is good practice and the sender
object is often useful during event handling.
EventGenerator - Event Generator
public class EventGenerator {
public event MyEventArgs.MyHandler SomeEvent;
public void fireEvent() {
if (SomeEvent != null) {
SomeEvent(this, new MyEventArgs());
}
}
}
The public event MyEventArgs.MyHandler SomeEvent;
line specifies the object should contain an event handler called SomeEvent
allowing event handlers matching the delegate MyEventArgs.MyHandler
. The method fireEvent
while not essential (it's content may be included in line with other code) shows how the event object fires events, i.e. generates an event to each of the attached event handlers. new MyEventArgs()
may be replaced with a MyEventArgs
object which has had inner properties set, and hence provide a more useful data transfer.
EventCatcher - Event Handling
public class EventCatcher {
public void g_SomeEvent(object sender, MyEventArgs e) {
Console.WriteLine("It happened in EventCatcher...");
}
}
Event handling requires simply creating a method matching the delegate associated with the event; this may be performed automatically by Microsoft Visual Studio (and otherwise) editors when attaching to an event generator.
Program - System Linking
static void Main(string[] args) {
EventGenerator g = new EventGenerator();
EventCatcher c = new EventCatcher();
g.SomeEvent += new MyEventArgs.MyHandler(g_SomeEvent);
g.SomeEvent += new MyEventArgs.MyHandler(c.g_SomeEvent);
g.fireEvent();
Console.ReadLine();
}
static void g_SomeEvent(object sender, MyEventArgs e) {
Console.WriteLine("It happened in Program...");
}
The Main
method links the event generator object g
to the event catcher object c
via g.SomeEvent += new MyEventArgs.MyHandler(c.g_SomeEvent)
; this line accesses the g.SomeEvent
event handler and adds to it a new MyHandler
delegate encapsulating the c.g_SomeEvent
method. Note, it is also possible to add static methods as event handlers as per g.SomeEvent += new MyEventArgs.MyHandler(g_SomeEvent)
. Finally to fire an event, a call to g.fireEvent()
is made.
Points of Interest
You won't learn anything interesting/fun/annoying while writing this kind of code. Neither will you do anything particularly clever or wild or zany. However, this code represents the fundamental use of the event system, so ditch the old Java style way and learn.
History
Version 1.000, basic example of the event system, complete.