This tutorial shows how to declare, invoke, and hooks up to events in C #.Tutorial
An event in C # is a-on-a-provide notifications to clients of the that class when some interesting thing Happens to an object. The most familiar use for events are in graphical user interfaces; Typically, the classes that represent controls in the interface has events that is notified when the user does something To the control (for example, click a button).
Events, however, need not being used only for graphical interfaces. Events provide a generally useful-in-a-objects to-signal state changes, may is useful to clients of the that object. Events is an important building block for creating classes, can be reused in a large number of different programs.
Events are declared using delegates. If you had not yet studied the Delegates Tutorial, you should did so before continuing. Recall that a delegate object encapsulates a method so the it can be called anonymously. An event is a-on-a-clients to give it delegates-to-methods that should was called when the event occurs . When the event is occurs, the delegate (s) given to it clients is invoked.
In addition to the examples on declaring, invoking, and hooking up to events, this tutorial also introduces the following Topics
- Events and inheritance
- Events in Interfaces
- . NET Framework Guidelines
Example
The following simple example shows a class, ListWithChangedEvent
which are similar to ArrayList
the standard class, but also invokes a Changed
E Vent whenever the contents of the list change. Such a general-purpose class could is used in numerous ways in a large program.
for example, a word processor might maintain a list of the open documents. Whenever this list changes, many different objects in the word processor might need to being notified so that the user Interf Ace could be updated. By using events, the code this maintains the list of documents doesn ' t need to know who needs to be notified-once the LI St of documents is changed, the event was automatically invoked and every object, needs to be notified was correctly not Ified. By using events, the modularity of the program is increased.
Events tutorial-chimomousing system;using system.collections;namespace eventstutorial{//A delegate type for hook ing up change notifications. public delegate void Changedeventhandler (object sender, EventArgs e); A class that works just like ArrayList, but sends event notifications whenever the list changes. Class Listwithchangedevent:arraylist {//an event this clients can use to be notified whenever the elements O F list change. public event Changedeventhandler Changed; Invoke the Changed event; Called whenever list changes. private void OnChanged (EventArgs e) {if (Changed! = null) {Changed (this, e); }}//Override Some of the methods that can change the list; Invoke event after each. public override int Add (object value) {int i = base. ADD (value); OnChanged (Eventargs.empty); return i; } public Override void Clear () {base. Clear (); OnChanged (Eventargs.empty); } public override Object This[int Index] {set {Base[index] = value; OnChanged (Eventargs.empty); } } }}
//Events Tutorial-chimomousing System;namespace eventstutorial{class EventListener {private ListWithChangedEvent L Istwithchangedevent; Public EventListener (listwithchangedevent list) {listwithchangedevent = list; Add "ListChanged" to the Changed event on "ListWithChangedEvent". Listwithchangedevent.changed + = ListChanged; }//This would be called whenever the list changes. private void ListChanged (object sender, EventArgs e) {Console.WriteLine ("This was called when the event Fires. "); public void Detach () {//Detach the event and delete the listwithchangedevent. Listwithchangedevent.changed-= ListChanged; ListWithChangedEvent = null; } }}
Events tutorial-chimomonamespace eventstutorial{ Static class program { //Test the ListWithChangedEvent class. static void Main () { //Create a new list. ListWithChangedEvent list = new ListWithChangedEvent (); Create a class that listens to the list's change event. EventListener listener = new EventListener (list); Add and remove items from the list. List. ADD ("Item 1"); List. Clear (); Listener. Detach ();}}} Output:/*this is called when the event fires. This was called when the event fires.*/
Code Discussion
- declaring an event To declare an event inside a class, first a delegate type for the event must was declared, if none is already declared.
public delegate void Changedeventhandler (object sender, EventArgs e);
The delegate type defines the set of arguments that is passed to the method that handles the event. Multiple events can share the same delegate type, so this step was only necessary if no suitable delegate type have already been declared.
Next, the event itself is declared.
public event Changedeventhandler Changed;
An event was declared like a field of delegate type, except that the keywordevent precedes the event declaration, Following the modifiers. Events usually is declared public, but any accessibility modifier is allowed.
- invoking an event Once A class have declared an event, it can treat that event just like a field of the indicated delegate type. The field would either be null, if no client have hooked up a delegate to the event, or else it refers to a delegate that SH Ould be called when the event is invoked. Thus, invoking an event was generally done by first checking for null and then calling the event.
if (Changed! = null) { Changed (this, e);}
Invoking an event can is only is done from within the class that declared the event.
- hooking up to an event From outside the class that declared it, an event looks like a field, but access to that field is very restricted. The only things that can is done is:
- Compose a new delegate onto that field.
- Remove a delegate from a (possibly composite) field.
This is do with the + = and-= operators. To begin receiving event invocations, client code first creates a delegate of the event type this refers to the method tha T should is invoked from the event. Then it composes this delegate onto any and delegates that the event might is connected to using+ =.
Add "ListChanged" to the Changed event on "ListWithChangedEvent1". listwithchangedevent1.changed + = ListChanged;
When the client code is do receiving event invocations, it removes its delegate from the event by using operator-= .
Detach the event and delete the listWithChangedEvent1.listWithChangedEvent1.Changed-= ListChanged;
Events and Inheritance
when creating a general component The can is derived from, what seems to is a proble M sometimes arises with events. Since events can invoked from within the class that declared them, derived classes cannot directly invoke events D Eclared within the base class. Although this is sometimes desired, often it's appropriate to give the derived class the freedom to invoke the EV Ent. This is typically do by creating a protected invoking method for the event. By calling this invoking method, derived classes can invoke the event. For even more flexibility, the invoking method was often declared as virtual, which allows the derived class to override it . This allows the derived class to intercept the events and the base class is invoking, and possibly doing its own processing o F them.
The preceding example, this have been done with the OnChanged
method. A derived class could call or override this method if it needed to.
Events in Interfaces
One other difference between events and fields are that an event can being placed in an interface while a field cannot. When implementing the interface, the implementing class must supply a corresponding event in the class that implements the Interface.
. NET Framework Guidelines
Although the C # language allows events to use any delegate type, the. NET Framework have some stricter guidelines on the DE Legate types that should is used for events. If you intend for your component to being used with the. NET Framework, you probably would want to follow these guidelines.
The. NET Framework guidelines indicate the delegate type used for a event should take-parameters, an "Object sou Rce "parameter indicating the source of the event, and an" E "parameter that encapsulates any additional information about The event. The type of the "E" parameter should derive from theEventArgs class. For events that does not use any additional information, the. NET Framework have already defined an appropriate delegate type :EventHandler.
C #-Events Tutorial