About events
To understand the event mechanism, you must first understand the delegation mechanism. Event mechanisms include event declarations, event triggers, and event responses. The event trigger becomes the "publisher", and the event responder becomes the "subscriber" of the event"
Event features:
The publisher determines when an event is triggered, and the user determines the operation to be performed to respond to the event.
An event can have multiple subscribers. One subscriber can process multiple events from multiple publishers.
Events without subscribers will never be triggered.
Events are usually used to notify users of operations. For example, you can click a button in the graphic user interface or select a menu.
If an event has multiple subscribers, multiple event handlers are synchronously called when the event is triggered. To call events asynchronously, see call synchronous methods in asynchronous mode.
In the. NET Framework class library, events are based on the EventHandler delegate and EventArgs base class.
Event publishing and subscription:
The release class of an event generally includes the declaration of the event and the excitation of the event (in fact, the response, but the delegate must be used in the response function ). The subscriber of an event needs to change the event publishing class.
Number (used to specify the function corresponding to the delegate), Event Response Function. Example:
class Publish { public event EventHandler eventName; //declare event named eventName public void inspireEvent() // inspire the event { onEventName(new EventArgs()); } public void onEventName(EventArgs e) // will use the scriber's method to reply the event { EventHandler handle = eventName; if (handle != null) { handle(this,e); } } }
class Scriber { public Scriber(Publish pb) { pb.eventName += howDo; // scribe the event } public void howDo(Object sender, EventArgs e) { Console.WriteLine("what a fuck day it is"); } }
class Program { static void Main(string[] args) { Publish ph = new Publish(); Scriber sb = new Scriber(ph); ph.inspireEvent();//motivate the event } }
Uniqueness of events:
An event is a delegate, but it is a special delegate,
The call event can only be in the declared event class., Such:
EventHandler handle = eventBase;eventBase(obj,e);
Only eventBase + = and eventBase-= can appear.
Therefore, if you want to call events in the base class, you can only use indirect methods, for example:
class BaseEvent { public event EventHandler baseEvent; public virtual void draw() { Console.WriteLine("This is in base draw"); } public virtual void onDraw(EventArgs e) { EventHandler handle = baseEvent; if (handle != null) { handle(this ,e); } Console.WriteLine("this is in base on"); } }
class Derived : BaseEvent { public override void draw() { //base.draw(); Console.WriteLine("this is in derived class"); } public override void onDraw(EventArgs e) { //EventHandler handle = baseEvent; //baseEvent(this, e); base.onDraw(e); } public void motivateDraw() { onDraw(new EventArgs()); } }
class Scribe { public Scribe(Derived dr) { dr.baseEvent += Motive; } public void Motive(Object sender, EventArgs e) { Console.WriteLine("what a fuck day"); } }
class Program { static void Main(string[] args) { Derived D = new Derived(); BaseEvent B = new BaseEvent(); Scribe Sb = new Scribe(D); D.motivateDraw(); } }
Implementation of interface events:
The implementation of interface events is basically the same as that of methods in interfaces. When subscribing to an event, the subscribed method is added to the Delegate's method list through the event accessor. The event accessor is similar to the attribute accessor, but the accessor is named add and remove. In most cases, the Custom Event accessors are not required, because the compiler will help us, but when the compiler cannot help us, we have to write the event accessors by ourselves. When multiple interfaces contain events with the same signature, you must use the event display definition, in addition, the interface is used to call the event subscription (similar to the attribute, indexer, and method). The example is as follows:
namespace ConsoleApplication16InterfaceEvent{ interface Iface { event EventHandler faceEvent; } interface Ifoot { event EventHandler footEvent; } interface Ihand { event EventHandler footEvent; } class InterEvent : Iface,Ifoot,Ihand { public event EventHandler faceEvent; //public event EventHandler footEvent; public event EventHandler preFootEvent; public event EventHandler nexHandEvent; Object objectLock = new Object(); event EventHandler Ifoot.footEvent { add { lock (objectLock) { preFootEvent += value; } } remove { lock (objectLock) { preFootEvent -= value; } } } event EventHandler Ihand.footEvent { add { lock (objectLock) { nexHandEvent += value; } } remove { lock (objectLock) { nexHandEvent -= value; } } } public void finger() { EventHandler handle = preFootEvent; if ( handle != null) preFootEvent(this,new EventArgs()); handle = nexHandEvent; if (handle != null) nexHandEvent(this,new EventArgs()); } }}
//...............namespace ConsoleApplication16InterfaceEvent{ class Scribe { public Scribe(InterEvent Et) { Ifoot foot = (Ifoot)Et; foot.footEvent += draw1; Ihand hand = (Ihand)Et; hand.footEvent += draw2; } void draw1(Object sender, EventArgs e) { Console.WriteLine("this is in Scribe draw1"); } void draw2(Object sender, EventArgs e) { Console.WriteLine("this is in Scribe draw2"); } }}
//..................namespace ConsoleApplication16InterfaceEvent{ class Program { static void Main(string[] args) { InterEvent EI = new InterEvent(); Scribe Sb = new Scribe(EI); EI.finger(); } }}