introduction
In the process of learning C #, I have read many articles to understand how they have something to use, and how to use them, now I will explain the following, every aspect I have learned. I am afraid it is also what you need to master :-).
What is a delegation?
The two concepts of commission and events are completely cooperated. The entrustment is just a function pointer, that is, it can reference the function, complete by the transmission of the address. The delegation is a class. When you instantiate it, provide a reference function to make it as a parameter of its constructor.
Each delegation has its own signature, for example: delegate int salesdelegate (String S, Bool B); is a delegate declaration, here, the signature mentioned, saying Somedelegate This entrusted String and BOOL types, return An Int type.
The above mentioned: When you are instantified to the entrusted, provide a reference function to construct a function of its constructor. Here you should pay attention to: This function being referenced must be the same signature as the commission.
Look at the functions below:
Private Int Somefunction (String Str, Bool BLN) {...}
You can pass this function to the constructor of Somedlegate because they have similar signatures (in Other Words, they have the same type of parameter type and number, and return the same data type).
SomeDelegate SD = New Somedlegate (SomeFunction);
SD references SomeFunction, that is, SomeFunction has been registered by SD, if you call SD, SomeFunction This function will be called, remember: I said the meaning of someFunction, behind, we will use it.
Now, you should know how to use entrusted, let us continue to understand incident ...
Event's understanding
We know, in C #:
l Button is a class that triggers a Click event when we click on it.
l Clock (Timer) is also a class, triggered a Tick event every time a millisecond.
Let us learn through an example, assume that there is such a plot:
There is a class of counters, which has a method countto (int COUNTTO, INT REACHABLENUM), which means: NumberReached when the specified time point Rechablenum is reached, when arriving at the specified time point REACHABLENUM event.
It also has an event: NumberReached, the event is a variable of the delegate type. Means: If you name it, use the Event keyword and the delegate type to use, you can declare it, as shown below:
Public Event NumberReacheventHandler NumberReached;
In the above statement, NumberReachedeventHandle is just a delegate, and more exactly should be: NumberReachedDelegate. But Microsoft never thinks like this, MouseDelegate or PaintdeLegate, but is called: mouseeventhandler or PainteventHandler. So NumberReachedeventhandler sounds more convenient than NumberReachedDelegate, OK? Ok, let us continue, now you know, before we declare the incident, you need to define the following form:
Public Delegate Void NumberReacheDeventHandler (Object Sender, NumberReachedeventargs E);
Now declare the NumberReachedEventHandle, which has a VOID return value, and Object, NumberReachedeventargs two ginseng. As we emphasized in the first quarter, when instantiate the entrustment, functions that are incorporated as the real parameters must also have and entrust the same signature.
In your code, have you used Painteventargs or MouseEventArgs to determine the mouse movement location? Is the graphics property used in the object that triggers the Paint event? In fact, the classes that provide data for users are inherited in the System.Eventargs class, which is the event parameter class we often say. If the event does not provide parameters, it is not defined. In our example, we provide expected time points by the following classes.
Public Class NumberReachedEventArgs: Eventargs
{
Private int _reached;
Public NumberReachedEventArgs (int Num)
{
THIS._REACHED = NUM;
}
Public int ReachedNumber
{
get
{
Return_Reached;
}
}
}
Ok, I have a previous introduction, let's go to the Counter class to see:
Namespace Events
{
Public Delegate Void NumberReacheDeventhandler (Object Sender,
NumberReachedEventArgs E);
///
/// Summary Description for counter.
/// summary>
Public Class Counter
{
Public Event NumberReacheventHandler NumberReached;
Public counter ()
{
//
// Todo: add constructor logic here
//
}
Public Void Countto (int COUNTTO, INT Reachablenu)
{
IF (countto Throw new argumentexception "Reachablenum Should Be Less Than Countto"); For (int Ctr = 0; CTR <= COUNTTO; CTR ) { IF (CTR == Reachablenum) { NumberReachedEventArgs E = New NumberReachedEventArgs (Reachablenum); OnnumberReached (e); Return; // Don't Count Any More } } } Protected Virtual Void OnNumberReached (NumberReachedeventArgs E) { IF (NumberReached! = NULL) { NumberReached (this, e); // raise the event } } } In Counter, if you arrive at the specified point in time, trigger an event, there is a few aspects: l Complete a trigger event by calling NumberReached (it is an instance of NumberReachedEventHandler delegate). NumberReached (this, e); In this way, all registration functions can be called. l Via NumberReachendEventArgs E = New NumberReachedEventArgs (Reachablenu); Event data is provided for all registration functions. l At the code above, you may have to ask: Why do we use the OnNumberReached (NumberReachedEventArgs E) method to call NumberReached (this, e) without using the following code? IF (CTR == Reachablenum) { NumberReachedEventArgs E = New NumberReachedEventArgs (Reachablenum); // OnNumberReached (e); IF (NumberReached! = NULL) { NumberReached (this, e); // raise the event } Return; // Don't Count Any More } This question is very good, let's take a look at the onNumberReached signature: Protected Virtual Void OnNumberReached (NumberReachedeventArgs E) 1 You also understand that the keyword protected defines all the methods in this class only from this class. 2 Keyword Virtual indicates that the method can be rewritten in the inheritance class. This is very useful, assuming that you write a class inherited from the Counter, by overridden the onNumberReached method, you can make another job before the event is triggered. Protected Override Void OnNumberReached (NumberReachedEventArgs E) { // Do Additional Work Base.onnumberReached (e); } Note: If you don't call Base.OnnumberReached (E), then never triggering this event! Using this way is very useful when you inherit this class. l 还 还: 是 是 是 是 是 是 是 是 是 是 是 是 是 是 是 是 是 是 是 是 是 是 是 是 是 是 是 是 是 是 是 的 的 的 的 的 Ok, let's actually use the Counter class. In our simple app, we have two text boxes, namely txtcountto and txtReachable: Below is the Click event of btnrun: private void btnrun_click (Object Sender, System.EventArgs E) { IF (txtcountto.text == "" || txtreachable.text == "") Return; OCOUNTER.COUNTTO (CONVERT.TOINT32 (TXTCOUNTTO.TEXT), CONVERT.TOINT32 (TXTREACHABLE.TEXT); } Private void Ocounter_NumberReached (Object Sender, NumberReachedeventargs E) { Messagebox.show ("reached:" E.REachedNumber.toString ()); } The syntax for initialization event processing is as follows: OCOUNTER = New Counter (); Ocounter.NumberReached = new numberReachedEventHandler (OCOUNTER_NUMBERREACHED); Now you understand everything you just made, just initialize the object of the NumberReachedEventHandler entrusted type (just like you instantiate other objects), notice that the signature of the OCOUNTER_NUMBERREACHED method is similar to what I mentioned earlier. Also note that we use = instead of =; this is because the delegate is a special object, which can reference multiple objects (here, it means that it can reference multiple functions). For example if there is another one The same signature function OCOUNTER_NUMBERREACHED2 is the same as OCOUNTER_NUMBERREACHED, and the two functions can be referenced: OCOUNTER = New Counter (); Ocounter.NumberReached = new numberReachedEventHandler (OCOUNTER_NUMBERREACHED); OCOUNTER.NUMBERREACHED = New NumberReachedEventHndler (Ocounter_NumberReached2); Now, after the event is triggered, the above two functions are called in turn. Depending on the situation, if you want ocounter_numberreached2 no longer call after the NumberReached event occurs, you can write this way: Ocounter.NumberReached - = New NumberReachedEventHandler (Ocounter_NumberReached2); At last Let us look at the complete source code for reference: Form1.cs Using System; Using System.drawing; Using System.collections; Using System.componentmodel; Using System.windows.forms; Using System.data; Namespace Events {/ ** /////////////// summary> public class form1: system.windows.forms.form {counter = null; private system.windows.form. Button cmdRun; private System.Windows.Forms.TextBox txtReachable; private System.Windows.Forms.TextBox txtCountTo; private System.Windows.Forms.Label label1; private System.Windows.Forms.Label label2; private System.Windows.Forms. Button btnRemoveDelegate;. / ** //// /// Required method for Designer support - do not modify /// the contents of this method with the code editor /// summary> private void InitializeComponent () {this.cmdRun = new System.Windows.Forms.Button. (); This.txtReachable = new system.windows.Forms.TextBox (); this.txtcountTo = new system.windows.forms.textbox (); this.label1 = new system.windows.forms.label (); this. Label2 = new system.windows.forms.label (); this.btnremovededeGate = new system.windows.forms.button (); this.suspendlayout (); // // cmdrun // this.cmdrun.location = new system. Drawing.point (16, 72); this.cmdrun.name = "cmdrun"; this.cmdrun.size = new system.drawing.size (48, 23); this.cmdrun.TabINDEX = 2; this.cmdrun.text = "Run"; this.cmdrun.click = new system.eventhandler (this.cmdrun_click); ///////////////////////////Ww system.drawing.point (144, 40); this.txtReachable.name = "txtreachable"; this.txtreachable.size = new system.drawing.size (56, 20); this.txtReachable.TabINDEX = 1; this.txtreachable.text = ""; /// txtcounttto // this.txtcountTtto.Location = new system.drawing.point (144, 16); this.txtcountto.name = "Txtcountto"; this.txtcountTto.size = new system.drawing.size (56, 20); THISTXTCOUNTTO.TABINDEX = 0; this.txtCountTto.text = ""; /// Label1 // this.label1.autosize = true; this.label1.location = new system.drawing.point (16, 16); THIS.LABEL1.NAME = "label1"; this.label1.size = new system.drawing.size (51, 13); this.label1.tabindex = 3; this.label1.text = "count to"; // / / Label2 // this.label2.autosize = true; this.label2.location = new system.drawing.point (16, 40); this.label2.name = "label2"; this.label2.size = new system.drawing .Size (99, 13); this.label2.tabindex = 4; this.label2.text = "reach this number"; // // btnremovedeGate // this.btnremovedeGate.location = new system.drawing.point (16, 104); this.btnremovedeLegate.name = "btnremovededegate"; T his.btnRemoveDelegate.Size = new System.Drawing.Size (168, 23); this.btnRemoveDelegate.TabIndex = 5; this.btnRemoveDelegate.Text = "Remove second handler"; this.btnRemoveDelegate.Click = new System.EventHandler ( This.btnremovedeLegate_Click); // // form1 // this.autoscalebasesize = new system.drawing.size (5, 13); this.clientsize = new system.drawing.size (224, 134); this.Controls.AddRange (new System.Windows.Forms.Control [] {this.btnRemoveDelegate, this.label2, this.label1, this.txtCountTo, this.txtReachable, this.cmdRun}); this.Name = "Form1" This.Text = "Events"; this.ResumeLayout (false);} #ENDREGON / ** //// } Private void btnRemoveDelegate_Click (object sender, System.EventArgs e) {oCounter.NumberReached - = new NumberReachedEventHandler (oCounter_NumberReached2); oCounter.CountTo (Convert.ToInt32 (txtCountTo.Text), Convert.ToInt32 (txtReachable.Text));}} } Counter.cs Using System; Namespace Events