zoukankan      html  css  js  c++  java
  • c# 委托与事件

    委托
    是C#中的一种引用类型,类似于C/C++中的函数指针(一个c++函数在编译时被分配给一个入口地址,这个入口地址就称为函数的指针)。
    委托是一个特殊的类,类的实例是对象,但委托的实例没有专门的名称。
    声明一个委托:
    public delegate void my_delegate_1(Object sender, EventArgs e);
    产生委托的实例:
    public delegate int my_delegate_2(int x,int y);
    class math_class 
    {
       public int sub(int x, int y)
       {
         return(x+y);
       }
     }
    my_delegate_2 del_example_1 = new my_delegate_2(math_class.sub);
    接下来可以直接使用del_example_1调用sub方法了:
    del_example_1(23,7)

    事件

    委托的最基本的一个用处就是用于事件处理。
    在类中声明一个事件成员一般采用如下的语法形式:
    public event 委托名 事件名
    事件的定义用关键字event声明,不过声明事件之前必须存在一个多路广播委托:
      public delegate void my_delegate_3(int x,int y);
    //返回值为void的委托自动成为多路广播委托.
    声明事件:  
      public event  my_delegate_3 my_event_1;
    如在Control类中声明了一个Click事件成员,其语法如下:
    public event EventHandler Click;

    Eventhandler是一个delegate
    类型,其在类库中声明如下:
    public delegate void EventHandler(object sender,EventArgs e);
    这样,所有形如:
    void 函娄名(object 参数名,EventArgs 参数名);
    的函数都可以作为Control类的Click事件响应方法了。
    其中第一个参数指明了触发该事件的对象即sender,由于引发事件的对象不可预知的,因此我们把其声明成为object类型,所有的对象都适用。
    第二个参数(e)包含了在事件处理函数中可以被运用的一些数据,各种类型的事件中可能不同,这要根据类中事件成员的说明决定。
    如下面所定义的一个事件响应方法:
    private void button1_Click(object sender, System.EventArgs e);
    由于是通过delegate来处理事件,因此,可通过 += 使一个事件具有多个响应方法;与此同时,还可以使一个方法作为多个事件的响应方法。

    实例:
    创建两个类,A类将提供事件的处理函数,并在步骤3中创建委托对象同时将事件处理函数包含在其中,事件处理函数的参数形式必须和委托对象的参数形式相一致然后,A类将委托对象传递给B类。当B类中的事件被触发后, A类中的事件处理函数就相应的被调用了。下面是示例代码:

    using System;
    //步骤1:声明委托
    public delegate void MyHandler1(object sender,MyEventArgs e);
    public delegate void MyHandler2(object sender,MyEventArgs e);

    //步骤2:创建事件处理函数的方法
    class A{
    public const string m_id="Class A";
    public void OnHandler1(object sender,MyEventArgs e){
    Console.WriteLine("I am in OnHandler1 and MyEventArgs is {0}",
    e.m_id);
    }
    public void OnHandler2(object sender,MyEventArgs e){
    Console.WriteLine("I am in OnHandler2 and MyEventArgs is {0}",
    e.m_id);
    }

    //步骤3:创建委托对象,并事件处理函数包含在其中同时设置好将要触发事件的对象
    public A(B b){
    MyHandler1 d1=new MyHandler1(OnHandler1);
    MyHandler2 d2=new MyHandler2(OnHandler2);
    b.Event1 +=d1;
    b.Event2 +=d2;
    }
    }

    //步骤4:通过委托对象(也就是触发事件)来调用被包含的方法
    class B{
    public event MyHandler1 Event1;
    public event MyHandler2 Event2;
    public void FireEvent1(MyEventArgs e){
    if(Event1 != null){
    Event1(this,e);
    }
    }
    public void FireEvent2(MyEventArgs e){
    if(Event2 != null){
    Event2(this,e);
    }
    }
    }
    public class MyEventArgs EventArgs{
    public string m_id;
    }
    public class Driver{
    public static void Main(){
    B b= new B();
    A a= new A(b);
    MyEventArgs e1=new MyEventArgs();
    MyEventArgs e2=new MyEventArgs();
    e1.m_id ="Event args for event 1";
    e2.m_id ="Event args for event 2";
    b.FireEvent1(e1);
    b.FireEvent2(e2);
    }
    }

    C#中的GUI的事件处理函数:

      完成GUI下的事件处理函数的基本方法和上面介绍的并没有什么多大区别,下面我们就通过上面的方法来完成一个简单的实例程序。该实例程序的主类 MyForm类是从Form类继承过来的。通过观察整段代码和相关的注解,你可以发现我们并没有给它声明委托对象并通过event关键字来引用该委托对象,那是因为GUI控件早就帮我们做好了该项工作,其委托对象是System.EventHandler。然而,我们还是要为各个控件定义方法(也就是事件的处理函数)并将它们包含在创建好的委托对象(System.EventHandler)中。那样,在用户和程序进行交互的时候,相应的事件处理函数就会被触发。具体代码如下:
    using System;
    using System.Drawing;
    using System.Collections;
    using System.ComponentModel;
    using System.Windows.Forms;
    using System.Data;

    public class MyForm Form{
    private Button m_nameButton;
    private Button m_clearButton;
    private Label m_nameLabel;

    private Container m_components = null;

    public MyForm(){
    initializeComponents();
    }
    private void initializeComponents(){
    m_nameLabel=new Label();
    m_nameButton = new Button();
    m_clearButton = new Button();

    SuspendLayout();

    m_nameLabel.Location=new Point(16,16);
    m_nameLabel.Text="Click NAME button, please";
    m_nameLabel.Size=new Size(300,23);

    m_nameButton.Location=new Point(16,120);
    m_nameButton.Size=new Size(176, 23);
    m_nameButton.Text="NAME";
    //创建委托对象,包含方法并将委托对象赋给按钮的Click事件
    m_nameButton.Click += new System.EventHandler(NameButtonClicked);

    m_clearButton.Location=new Point(16,152);
    m_clearButton.Size=new Size(176,23);
    m_clearButton.Text="CLEAR";
    //创建委托对象,包含方法并将委托对象赋给按钮的Click事件
    m_clearButton.Click += new System.EventHandler(ClearButtonClicked);

    this.ClientSize = new Size(292, 271);
    this.Controls.AddRange(new Control[] {m_nameLabel,
    m_nameButton,
    m_clearButton});
    this.ResumeLayout(false);
    }
    //定义方法(事件的处理函数),其参数形式必须和委托对象的一致
    private void NameButtonClicked(object sender, EventArgs e){
    m_nameLabel.Text=
    "My name is john, please click CLEAR button to clear it";
    }
    private void ClearButtonClicked(object sender,EventArgs e){
    m_nameLabel.Text="Click NAME button, please";
    }
    public static void Main(){
    Application.Run(new MyForm());
    }
    }




    URL:http://blog.chinaunix.net/u/13205/showart_70291.html
  • 相关阅读:
    《网络攻防技术与实践》第六周学习总结
    《网络攻防技术与实践》第五周学习总结
    《网络攻防技术与实践》第四周学习总结
    《网络攻防技术与实践》第三周学习总结
    20159302《网络攻击与防范》第十一周学习总结
    20159302《网络攻击与防范》第十周学习总结
    20159302《网络攻击与防范》第九周学习总结
    20159302《网络攻击与防范》第八周学习总结
    20159302《网络攻击与防范》第七周学习总结-2
    20159302《网络攻击与防范》第七周学习总结
  • 原文地址:https://www.cnblogs.com/yiki/p/684990.html
Copyright © 2011-2022 走看看