The following article is my self-written code analysis that I think about the "event" mechanism, but after writing, the monks have a fear of understanding the deviation, so the special post came out to teach one or two, if you can find it Understand the mistake, will not be grateful (this question is completely "independent self-owner", not plagiarism)
At the same time, I believe this article has a certain help to C # beginners!
In order to explain clear, the exemplary will be explained; this example is completely customizes a set of events in one control, and the event is stimulated in another program (that is, the event is excited to call a predefined method).
I. Control body code and corresponding profiles containing custom events (note that this control library is generated by "New" -> "Windows Control Library" by VS.NET)
Namespace myEventTest {public class logineventArgs: system.eventargs // The above code defines all information that needs to be passed to the main program when incurred in the main program, and note that // must be derived from system.eventargs class {public logineventargs ( String suserid, string spassword, bool bvalid) {userid = suserid; password = spassword; valid = bvalid;}
Public String UserId; Public Bool Valid;
public delegate void GoodLoginEventHandler (object sender, LoginEventArgs e); public delegate void FailedThreeTimesEventHandler (object sender, LoginEventArgs e); // The above two lines define two multiplex delegate (return type must therefore void), corresponding to each commissioned One type of event; // because it is multiple delegation, so each delegate can contain multiple methods. // Please note that the parameter is (Object Sender, Logineventargs E), so the method added to multiple delegation must match This signature method. // In addition, why don't use the system that has defined multiple delegates "System.Event Sender (Eventargs E)", // to define new entrusted "???? EventHandler "?" This is because we pass the parameters of the user assembly here is not // "System.EventArgs" type, but it is a "logineventargs" type that you define, so it is necessary to redefine your own commission type.
public class ActiveLogin: System.Windows.Forms.UserControl {private System.Windows.Forms.Label label1; private System.Windows.Forms.Label label2; private System.Windows.Forms.TextBox txtUserID; private System.Windows.Forms.TextBox txtPass; private System.Windows.Forms.Button btnLogin; private System.Windows.Forms.Button btnCancel; private System.ComponentModel.Container components = null; // some components defined above is composed of the code of this control, automatically by VS.NET generate
public event GoodLoginEventHandler GoodLogin; public event FailedThreeTimesEventHandler FailedThreeTimes; public event EventHandler Cancel; // above three lines of code is very important to define the three events (event), respectively, "GoodLogin", "FailedThreeTimes" // and "Cancel" / / They are "GoodLogineventrandler", "Failedthreetimeseventhandler" // and "Eventhandler", that is, the method added to these three events must meet the corresponding multi-purpose delegation definition! // and pay attention, because of the event "Cancel "The type is the system-defined multi-channel" EventHandler "type, //, so there is no new delegation similar to" CanceleventHandler "in the multi-channel delegate, because it is not required. Public activein () {initializationComponent (); } // The above code is the constructor of the class "active" ", which calls the initialization inTILALIZECMOMPONENT () //, automatically generated by VS.NET {if (Disposing) {if (disposing) {ix IF (Components! = null) {Components.dispose ();}} Base.dispose ();} // The above code is the destructure method of custom controls "ActiveLogin", automatically generated by vs.net.
Private vidinitis () {.... // Here is the initialization code for all reference controls (components)} // The above code is the initial method of the class "active" in the custom control, where the content is automatically generated by vs.net .
Protected Virtual Void ONGOODLOGIN (Logineventargs E) // The above line code defines the method of exciting "GoodLogin" event; // Note that the signature type, the definition method is protected by protected virtual, that is, it can only be in this class and its // inherited class This method can be rewritten. // Parameter type is "logineventargs", pay attention to only this parameter, because in this method, it contains a reference to // this, so it does not need to pass the THIS object. // Generally Say, there are only two cases of this method: // <1> is called in this content, because the method is not called, it is not possible to stimulate the user code in the event "Goodlogin" // method; // <2 > Remote this method in the user's inheritance code, although the rewrite method may bring performance, but if you forget this method in user code, then in the user code, in the event "Goodlogin" in the event "Goodlogin" The addition method will not be activated !!! (Avoid this method of this problem must contain // "Base.googin (E)" in the rewriting method, this line will be responsible for calling this method) // For the No. 2> Points need to be put forward, the role of rewriting this method in the user's inheritance code is equivalent to adding a method to the // event "GoodLogin", the code content and rewrite method of this method are the same. // (but should absolute No "Base.googin (e)" this line) {if (GoodLogin! = NULL) // If you contain a method in the event "Googlogin", these methods are excited to {GoodLogin (this, e); // Put the THIS object and Parameter E passed to all event "googlogin" // The method added is, and these methods are performed sequentially (note that the method is determined by multiple // delegate: the method added first in the user code is first executed first.}} // The above explanation is very detailed, The following two ON methods are all except the above ON methods .Protected Virtual Void onfailedthreetimes (logineventargs e) {if (failedthreetimes! = Null) {Failedthreetimes (this, e);}}
Protected Virtual Void Oncancel (System.EventArgs E) {if (Cancel! = NULL) {Cancel (this, e);}} private void btnlogin_click (object sender, system.eventargs e) // The above definition is vs.net Automatic generation, is the method called when the "btnlogin" button is pressed. {If (...) ONGOODLOGIN (NEW Logineventargs (TXTUSERID.TEXT, TRUE)); // The above line code calls ONGOODLOGIN Method, action is "When the button btnlogin in the control is pressed, // and conform to the above IF condition: // will add all methods to the user code to the event" Googlogin "by calling the ONGOODLOGIN method //// All sequences are executed again. // Why don't you perform the code in the ONGOODLOGIN () method here, but also call ONGOODLOGIN / / method separately? This is because sometimes the user code needs to overwrite the overgogin () method! // OnFailedThreeTimes following call () method and the OnCancel () method explained above else OnFailedThreeTimes (new LoginEventArgs (txtUserID.Text, txtPass.Text, false));.} private void btnCancel_Click (object sender, System.EventArgs e) {oncancel (new evenetargs ());}}}
II. Call the assembly of this control (note that this assembly is generated by the "New" -> "Windows Application" of VS.NET), that is, the "User Code" section
Namespace Hostapp {public class form1: system.windows.forms.form {private myeventtest.activelogin activein1; // The above line code references the class "active" "ActiveLogin" for custom control libraries, and defines an object "ActiveIn1". // The "MyEeventtest" here is the namespace defined in the custom control library. If the // "Using MyEventTest" statement appears in this program, the name must appear in any code referenced by the custom control!
Private system.componentmodel.Container Components = NULL;
Public form1 () {initializationComponent ();
Protected Override Void Dispose (bool disposing) {if (disponents! = null) {components.dispose ();}} Base.Dispose ();} // The above two methods are also vs.net Automatic generation, do not explain other explanations .private voidin1 = new myEventtest.activelogin (); // The above line code With the custom control library "ActiveLogin" instantiated object "ActiveIn1" this.suspendlayout ();
// // ActiveLogin1 // this.activeLogin1.Location = new system.drawing.point (144, 8); this.activeLogin1.name = "active11"; this.activeLogin1.size = new system.drawing.size (280, 184); this.activeLogin1.tabindex = 0;
this.activeLogin1.GoodLogin = new MyEventTEST.GoodLoginEventHandler (this.activeLogin1_GoodLogin); this.activeLogin1.Cancel = new System.EventHandler (this.activeLogin1_Cancel); this.activeLogin1.FailedThreeTimes = new MyEventTEST.FailedThreeTimesEventHandler (this.activeLogin1_FailedThreeTimes) ; // !!! Please pay attention to the three lines of code above, this is the code that the user code accepts the event of the event in the custom control library !! // The above three lines of code respectively define the user-defined method "activein1_goodlogin", "ActiveIn1_cancel" / / And "activein1_failedthimes" Add to the event "Googlogin", "Cancel" // and "FaileDthreetimes" in the custom control; this way as long as the corresponding event in the control is excited, these // add users The definition method will be executed. // It is to be noted that the user-defined method signature must meet the definition of the corresponding multi-purpose entrustment (because the event is delegated // defined, so what the event is added, defined The definition of the multi-channel delegate must be in accordance with the event) //, and the CANCEL event type here is the type of multiple delegate "EventHandler" that the system has defined, so its instantiation / / instantiation with other two events Different, "System.EventHandler" instead of "MyEventtest.EventHandler"! // These users The custom method will be listed below. // However, please note that although the three lines of code above is in the method initializeComponent (), but we have handicapped! // // form1 // this.autoscalebasesize = new system .Drawing.size (5, 13); this.clientsize = new system.drawing.size (440, 357); this.controls.addrange (new system.windows.forms.control [] {this.activeLogin1,}); THIS.NAME = "Form1"; this.text = "form1"; this.ResumeLayout (false);}
[Stathread] static void main () {Application.run (new form1 ());} // The above method is the entry of the Windows Forms program, respectively.
private void activeLogin1_GoodLogin (object sender, MyEventTEST.LoginEventArgs e) {MessageBox.Show ( "Good Login!" e.UserID);} private void activeLogin1_FailedThreeTimes (object sender, MyEventTEST.LoginEventArgs e) {MessageBox.Show ( "Failed to login Three Times. ");
private void activeLogin1_Cancel (object sender, System.EventArgs e) {MessageBox.Show ( "Cancel");} // the above three methods (activeLogin1_GoogLogin, activeLogin1_Cancel and activeLogin1_FailedThreeTimes) // custom event is when the corresponding excited The processing method corresponding to the current program is concentrated. // It is worth noting that the signature should fully comply with the corresponding multi-purpose delegate!}