C # delegate, Getting Started with event understanding

Source: Internet
Author: User
Directory

L Introduction

L What is a delegate

L Understanding of Events

L Event keyword

L finally



Introduction

In learning about delegates and events in C #, I read a lot of articles to understand what they are and how to use them, and now I'm going to present the whole process of understanding to the following, and I'm afraid you need to master the:-) in every aspect I've learned.

What is a delegate?

The two concepts of delegates and events are fully matched. A delegate is simply a function pointer, which means that it can refer to a function and complete it by passing the address mechanism. A delegate is a class that, when you instantiate it, provides a reference function as a parameter to its constructor.

Each delegate has its own signature, for example: Delegate int somedelegate (string s, bool b); Is a delegate declaration, here, the signature mentioned here, that is, somedelegate this delegate has a parameter of string and bool type, Returns an int type.

mentioned above: When you instantiate a delegate, you provide a reference function as a parameter to its constructor. Note here: The referenced function must have the same signature as the delegate.

Look at the following function:

PRivate int SomeFunction (string str, bool bln) {...}

You can pass this function on to the Somedelegate constructor, because they have similar signatures (in the other Words, they all have the same parameter type and number, and return the same data type).

Somedelegate sd = new Somedelegate (SomeFunction);

SD refers to the SomeFunction, that is, SomeFunction has been registered by the SD, if you call sd,somefunction This function will also be called, remember: I said the meaning of SomeFunction, behind, we will use it.

Now, you should know how to use the delegate, let's continue to understand the event journey ...

Understanding of events

We know that in C #:

The L button is a class that fires a click event when it is clicked.

The L clock (Timer) is also a class that triggers a tick event every millisecond.


Let's take an example to learn, assuming there is such a plot:

There is now a counter class, which has a method countto (int countto, int reachablenum), which means: within a specified time period (0~~countto), when the specified point in time Reachablenum, The numberreached event is triggered once.

It also has an event: numberreached, the event is a variable of the delegate type. This means: If you name the event, declare it using the event keyword and the type of delegate you want to use, as shown here:

public event Numberreachedeventhandler numberreached;



In the above statement, Numberreachedeventhandle is only a delegate, and a more precise indication should be: numberreacheddelegate. But Microsoft does not think so mousedelegate or paintdelegate, but the title: MouseEventHandler or Painteventhandler. So

Numberreachedeventhandler more convenient than numberreacheddelegate, OK? Okay, let's go, now you know, before we declare an event, we need to define the delegate in a form like this:

public delegate void Numberreachedeventhandler (object sender, Numberreachedeventargs e);

Now the declared delegate Numberreachedeventhandle, it has a void return value, and a Object,numberreachedeventargs two parameters. As we emphasized in the first section, when instantiating a delegate, the function passed in as an argument must also have and delegate the same signature.

In your code, have you ever used PaintEventArgs or MouseEventArgs to determine where the mouse is moving? is the graphics property used in the object that triggered the paint event? In fact, the class that provides the data to the user is inherited from the System.EventArgs class, which is what we often call the event argument class, and if the event does not provide a parameter, the class is not defined. In our example, we provide the expected point in time through the following classes.

public class Numberreachedeventargs:eventargs

{

private int _reached;

public numberreachedeventargs (int num)

{

this._reached = num;

}

public int Reachednumber

{

Get

{

return _reached;

}

}

}

Well, with the previous introduction, let's take a look inside the counter class:

Namespace Events

{

public delegate void Numberreachedeventhandler (object sender,

Numberreachedeventargs e);



<summary>

Summary description for Counter.

</summary>

public class Counter

{

public event Numberreachedeventhandler numberreached;



Public Counter ()

{

//

Todo:add constructor Logic here

//

}

public void Countto (int countto, int reachablenum)

{

if (Countto < Reachablenum)

throw New ArgumentException (

"Reachablenum should is 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 a specified point in time, the event is triggered, and there are several things to note:

L completes a trigger event by calling Numberreached (which is an instance of the Numberreachedeventhandler delegate).

Numberreached (this, e); In this way, all the registration functions can be called.

L via Numberreachedeventargs e = new Numberreachedeventargs (reachablenum); Provides event data for all registered functions.

Looking at the code above, you may have to ask: why do we use the onnumberreached (Numberreachedeventargs e) method to invoke numberreached (this,e) instead of 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

}

That's a good question, so let's take a look at the onnumberreached signature:

protected virtual void onnumberreached (Numberreachedeventargs e)

① you also understand that the keyword protected restricts only classes that inherit from the class to invoke all methods in that class.

The ② keyword, virtual, indicates that the method can be overridden in an inherited class.

These two points are very useful, assuming you're writing a class that inherits from counter, and by overriding the Onnumberreached method, you can do another job before the event fires.



protected override void Onnumberreached (Numberreachedeventargs e)

{

Do additional

Base. Onnumberreached (e);

}

Note: If you do not call base. Onnumberreached (e), then this event will never be triggered! It is useful to use this method when you inherit the class and want to get out of some of its other events.

L Also note that the delegate numberreachedeventhandler is defined outside of the class definition and is visible to all classes.

Well, let's do the actual operation using the Counter class.



In our simple application, we have two text boxes, namely: Txtcountto and txtreachable:




The following is the Btnrun click event:

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 initializing event handling is as follows:

Ocounter = new Counter ();

ocounter.numberreached + = new Numberreachedeventhandler (ocounter_numberreached);



Now that you understand what you just did, just initialize the object of the Numberreachedeventhandler delegate type (just as you instantiate other objects), notice that the signature of the Ocounter_numberreached method is similar to the one I mentioned earlier.

Also note that we use + = rather than =; This is because the delegate is a special object that can reference multiple objects (in this case it can refer to multiple functions). For example if there is another

As with ocounter_numberreached functions with the same signature ocounter_numberreached2, both functions can be referenced:



Ocounter = new Counter ();

ocounter.numberreached + = new Numberreachedeventhandler (ocounter_numberreached);

ocounter.numberreached + = new Numberreachedeventhandler (OCOUNTER_NUMBERREACHED2);

Now, after triggering an event, the above two functions are called sequentially.



As the case may be, if you want Ocounter_numberreached2 to stop being called after the numberreached event, you can simply write this: ocounter.numberreached-= new Numberreachedeventhandler (OCOUNTER_NUMBERREACHED2);



Finally, let's take a 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>
Summary description for Form1.
</summary>
public class Form1:System.Windows.Forms.Form
{
Counter ocounter = null;

Private System.Windows.Forms.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;
/**////<summary>
Required designer variable.
</summary>
Private System.ComponentModel.Container components = null;

Public Form1 ()
{
//
Required for Windows Form Designer support
//
InitializeComponent ();

//
Todo:add any constructor code after InitializeComponent call
//
Ocounter = new Counter ();
ocounter.numberreached + = new Numberreachedeventhandler (ocounter_numberreached);
ocounter.numberreached + = new Numberreachedeventhandler (OCOUNTER_NUMBERREACHED2);
}

/**////<summary>
Clean up any resources being used.
</summary>
protected override void Dispose (bool disposing)
{
if (disposing)
{
if (components! = NULL)
{
Components. Dispose ();
}
}
Base. Dispose (disposing);
}

Windows Form Designer generated code#region Windows Form Designer generated code
/**////<summary>
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.btnremovedelegate = 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);
//
Txtreachable
//
This.txtReachable.Location = new 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 = "";
//
Txtcountto
//
This.txtCountTo.Location = new System.Drawing.Point (144, 16);
This.txtCountTo.Name = "Txtcountto";
This.txtCountTo.Size = new System.Drawing.Size (56, 20);
This.txtCountTo.TabIndex = 0;
This.txtCountTo.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";
//
Btnremovedelegate
//
This.btnRemoveDelegate.Location = new System.Drawing.Point (16, 104);
This.btnRemoveDelegate.Name = "Btnremovedelegate";
This.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);

}
#endregion

/**////<summary>
The main entry point for the application.
</summary>
[STAThread]
static void Main ()
{
Application.Run (New Form1 ());
}

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 ());
}
private void Ocounter_numberreached2 (object sender, Numberreachedeventargs e)
{
MessageBox.Show ("Reached2:" + e.reachednumber.tostring ());
}

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
{
public delegate void Numberreachedeventhandler (object sender, Numberreachedeventargs e);

/**////<summary>
Summary description for Counter.
</summary>
public class Counter
{
public event Numberreachedeventhandler numberreached;

Public Counter ()
{
//
Todo:add constructor Logic here
//
}
public void Countto (int countto, int reachablenum)
{
if (Countto < Reachablenum)
throw new ArgumentException ("Reachablenum should is 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);
}
}
}

public class Numberreachedeventargs:eventargs
{
private int _reached;
public numberreachedeventargs (int num)
{
this._reached = num;
}
public int Reachednumber
{
Get
{
return _reached;
}
}
}
}

The above is the C # Delegate, event understanding of the content, more relevant content please pay attention to topic.alibabacloud.com (www.php.cn)!

  • Related Article

    Contact Us

    The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

    If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.