Formally, the event can be of any delegate type. However, there is a special constraint for event considered as a recommended practice: the event should declared using the delegate type
System.EventHandler
or generic delegate type
EventHandler<TEventArgs>
where
TEventArgs
is
System.EventArgs
. By many reasons, it's best to follow this recommendation. For example FxCop (
http://en.wikipedia.org/wiki/FxCop[
^]) will require following this Microsoft rule by default.
That said, you can declare your event using non-generic
System.EventHandler
is you don't have any custom data to be passed to the even when you fire it. In this case you need to pass
sender
(which is the normally is same instance of the class which fires the event) and an instance of
System.EvenArgs
which does not carry any usual information. For example, your class (such as User Control) can declare even Click which only carry information on what is clicked, without any information on what's clicked (mouse coordinate, keyboard state, control state or anything else):
class MyControl {
public event EventHandler Click;
void FireClick() {
if (Click != null)
Click(this, new System.EventArgs());
}
}
To pass any number of custom parameters you should use generic version of
EventHander
. The declaration of event needs two steps. First, you need to create a type for generic parameter. According to generic type parameter constraint, it should be a class derived from
System.EvenArgs
, for example:
[System.Flags]
public enum MyControlStates = { None, }
public class MyCustomEventArgs : System.EventArgs {
internal MyCustomEventArgs(MyControlStates stated, System.Drawing.Point mouseCoordinates) {
}
public System.Drawing.Point MouseCoordinates { get { } }
public MyControlStates MyControlStates { get { } }
}
Now you can declare the event itself:
class MyControl {
public event EventHandler<MyCustomEventArgs> StateChanged;
void FireStateChanged() {
if (StateChanged != null)
StateChanged(this, new MyCustomEventArgs());
}
}
You did not ask about setting event handlers, but I recommend to use anonymous delegates in all cases; and for C# v.3 or later (you're using v.4) the best form of it is lambda:
MyControlInstance.StateChanges += (sender, eventArgs) => {
};
This is the most convenient, because you don't have to have a separate method for every event with strictly the same parameters (some of parameters are often not used, why reproduce them), you can even write all the code immediately in the anonymous method (I recommend it only in simple cases). Moreover, with lambda even type name are not needed: types are inferred from the event type (
type inference).
See more on using events:
how to call keydown event on particular button click[
^].
—SA