在这个程序里,这里的修改是为了更好理解,当然这种写法是语法错误的。

下面我们对其进行分析:

首先,观察“=”右面的表达式。

new System.EventHandler(this.button1_Click);

通过6.1.1一节中的说明,大家可以发现,这段代码实际上是建立了一个委托类型的实例,并让该委托指向了this.button1_Click方法。也就是说,在程序运行的“某一时刻”,系统会通过这个委托实例间接的调用this.button1_Click方法。

然后,我们再来观察“=”左面的表达示。在C风格的语言中“=”是赋值表达式,也就是说,“=”两侧表达式的数据类型应该是一样的。因此,既然“=”右侧的表达式是一个委托类型(System.EventHandler)的实例,那么this.button1.Click也应该是一个委托类型(System.EventHandler)。

通过上面的说明,我们得到一个信息,前面这段事件注册代码,是让this.button1.Click和System.EventHandler(this.button1_Click)指向了同一段内存空间,简单来讲,就是让this.button1.Click指向了this.button1_Click方法,调用了this.button1.Click,就相当于调用了this.button1_Click方法。因此,我们说,当this.button1的Click事件发生之后,方法this.button1_Click就会被调用。

在程序运行的时候,系统会自己检测this.button1是否被点击了,如果被点击了,就在button1的内部调用button1.Click,这时,Windows窗口中的button1_Click方法就会被执行。

当然,事件注册代码完全可以手写。因为,除了控件中事件注册代码是自动生成以外,其他类中的事件注册都是手写的。手工注册事件的方法如下:

首先,可以在事件发生之前的任何代码中添加事件(通常是在窗口的构造方法中),下面我们来手工注册button1的MouseMove事件,如下图所示:

当我们写完“=”时,会出现一个提示“Press TAB to insert”,这时,我们只需要按2下“TAB”键,事件的注册以及用于回调的方法,就会自己添加到代码窗口里,如下图所示:

自动生成的代码是将this.button1的MouseMove事件指向了button1_MouseMove方法。这样手写的代码和IDE自动生成的代码是完全一样的。

当然,作为控件的事件,我们完全可以自动生成,如果想自动生成button1的其他事件,只需要查看button1的属性窗口,并点击“”按钮,就会出现该控件的事件列表,如下图所示:

然后双击你想要的事件,代码就会自动生成了。

在前的面代码中为了更好理解事件注册,我们曾将

this.button1.Click += new System.EventHandler(this.button1_Click);

修改为

this.button1.Click = new System.EventHandler(this.button1_Click);

我们会发现,无论是自己写的事件注册代码,还是自动生成的代码,都是使用“+=”来实现的,实际上,作为事件注册的代码,我们仅仅能够使用“+=”来实现注册,简单的使用“=”是语法错误的!!!

“+=”操作符在C风格语言中是常用的操作符,比如

int i=0;

i+=1;

等同于

int i=0;

i=i+1;

因此,

this.button1.Click += new System.EventHandler(this.button1_Click);

在原则上等同于

this.button1.Click = this.button1.Click +

new System.EventHandler(this.button1_Click);

用自然语言来描述上面的代码就是“一个委托=这个委托本身+另外一个委托”。那么委托相加意味着什么呢?

在6.1.3一节中,我们讨论过MultiDelegate(多播委托),而事件本身也是委托,并且所有委托都是System.MultiDelegate类的派生类,在6.1.3中,我们曾经演示过,多个委托类型实例相加,就是将这些委托实例存放在一个多播委托的调用链中,当调用多播委托时,该多播委托的调用链中的所有委托都会顺序的被调用。

利用多播委托的原理,我们可以将多个方法注册给一个事件,如下所示:

this.button1.Click +=new System.EventHandler(this.button1_Click);

this.button1.Click +=new System.EventHandler(this.button1_Click1);

this.button1.Click +=new System.EventHandler(this.button1_Click2);

上面的代码,就将三个方法注册到了button1的Click事件中,当button1的Click事件触发之后,方法button1_Click,button1_Click1,button1_Click2将会被顺序调用。这样作的好处是,我们可以将多个功能以及逻辑完全独立的操作放在不同的方法中,当事件发生之后,这些方法将会顺序的被调用,以实现我的需要的级联操作。

6.2.3 控件中事件的回调方法

说完了事件的注册,下面我们来谈一下事件的回调方法。首先,我们还要再一次回顾事件注册的代码:

this.button1.Click +=new System.EventHandler(this.button1_Click);

上面代码中,使用“new System.EventHandler(this.button1_Click)”将一个System.EventHandler委托类型的实例指向了this.button1_Click方法。通过6.1.1一节中所谈到的内容,我们知道,如果想让一个委托指向一个方法,那么该委托以及所被指向的方法一定要具备相同的签名(Signature,具备相同的参数列表,相同的返回值)。因此,System.EventHandler类型和this.button1_Click方法具备相同的签名,下面,我们来看一下System.EventHandler委托的签名是什么样的:

public delegate void EventHandler(

Object sender,

EventArgs e

)

System.EventHandler的签名是:返回值为void;有两个参数,Object sender, EventArgs e。因此button1_Click方法也具备相同形式,代码如下:

private void button1_Click(object sender, EventArgs e)

{

}

实际上,我们所能够看到的事件回调方法的签名基本上都着不多,只不过第二个参数略有区别,下面,我们对该方法的参数进行说明。

Ø         Object sender

从该参数的命名上,可以看出其作用,sender(发送者)的意思是:谁触发的这个事件,那么sender就是谁,由于所有的类型在理论上讲都可以包括事件,因此sender的类型被定义成Object类型,当多个事件同时指向一个事件回调方法的时候,通过该参数可以区分出是哪一个类触发的事件,以便做出不同的处理,此时,需要对参数sender作出类型转化。

l         案例操作020603:多个事件指向同一个回调方法

首先,添加三个Button,一个TextBox

界面如下:

然后,在主窗口中添加一个方法ButtonClick,这三个按钮的Click事件将调用该方法。

代码如下:

protected void ButtonClick(object sender, EventArgs e)

{

Button bt = sender as Button;

this.textBox1.Text ="我是:"+ bt.Text;

}

上面代码中,为了知道点击的是哪个按钮,我们将sender转化成了Button类型。

下面来指定这三个按钮的Click事件回调方法

首先,切换到button1的属性窗口(F4),点击“”按钮,找到“Click”事件,并设置所调用的方法名为ButtonClick ,如下图所示。

然后,以相同的方法设置button2,button3的Click事件,并它们都指向ButtonClick方法。

最后,运行程序,下面是运行情况:

点击button1:

this.button1.Click += new System.EventHandler(this.button1_Click);的更多相关文章

  1. [C# 基础知识系列]专题五:当点击按钮时触发Click事件背后发生的事情 (转载)

    当我们在点击窗口中的Button控件VS会帮我们自动生成一些代码,我们只需要在Click方法中写一些自己的代码就可以实现触发Click事件后我们Click方法中代码就会执行,然而我一直有一个疑问的—— ...

  2. C#委托与事件

    一.在控制台下使用委托和事件 我们都知道,C#中有"接口"这个概念,所谓的"接口"就是定义一套标准,然后由实现类来具体实现其中的方法,所以说"接口,是 ...

  3. 用winform程序来了解委托和事件

    一.浅谈委托 如果有个过winform 和webform 程序开发的小伙伴一定有个这样的感觉吧,点击Button直接就执行了那个方法,到此他是怎么实现了的呢,大家有考虑过没有? 回到正题,什么是委托呢 ...

  4. 【总结】C# 设置委托的机理和简要步骤

    [引语]实际上,和Winform打交道的第一天呢,我们就已经接触了委托,例如当双击button产生button1_click,这个呢,是对button1点击事件的处理方法,至于委托和订阅事件,就悄悄的 ...

  5. Winform窗体的基本控件

    一.窗体的事件 每一个窗体都有一个事件,这个窗体加载完成之后执行哪一段代码 位置:(1)右键属性→事件→load 双击进入.(2)双击窗体任意一个位置进入 public partial class F ...

  6. C#之事件

    事件,是C#编程模型中重要的一个概念,通过对事件的理解,可以更好的了解C#程序运行机制.C#中的事件,可以简单的理解为类或者对象发生了一件事,并且把这件事通知给了其他的类或者对象,其他的类或者对象可以 ...

  7. asp.net C#获取程序文件相关信息

    代码如下 复制代码 using System.Reflection;using System.Runtime.CompilerServices; //// 有关程序集的常规信息是通过下列// 属性集控 ...

  8. WebClient.DownloadFile(线程机制,异步下载文件)

    线程机制(避免卡屏),异步下载文件. 我做网站的监控,WebClient.DownloadFile这个方法是我经常用到的,必要的时候肯定是要从网上下载些什么(WebRequest 也可以下载网络文件, ...

  9. C# 开发2048小游戏

    这应该是几个月前,闲的手痒,敲了一上午代码搞出来的,随之就把它丢弃了,当时让别人玩过,提过几条更改建议,但是时至今日,我也没有进行过优化和更改(本人只会作案,不会收场,嘎嘎),下面的建议要给代码爱好的 ...

随机推荐

  1. Tomcat目录下文件详解

    一.Tomcat背景   (转) 自从JSP发布之后,推出了各式各样的JSP引擎.Apache Group在完成GNUJSP1.0的开发以后,开始考虑在SUN的JSWDK基础上开发一个可以直接提供We ...

  2. hdu_5707_Combine String("巴卡斯杯" 中国大学生程序设计竞赛 - 女生专场)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5707 题意:给你三个字符串 a,b,c,问你 c能否拆成a,b,a,b串的每一个字符在c中不能变 题解 ...

  3. jsoup抓取数据

    jsoup的主要功能如下: 1. 从一个URL,文件或字符串中解析HTML: 2. 使用DOM或CSS选择器来查找.取出数据: 3. 可操作HTML元素.属性.文本: 接下来介绍jsoup 是如何优雅 ...

  4. Mysql5.7 安装

    1 安装yum源 yum localinstall http://repo.mysql.com//mysql57-community-release-el7-7.noarch.rpm2 参看源 vi ...

  5. 解析:DNS 原理(入门篇)

    DNS 是互联网核心协议之一.不管是上网浏览,还是编程开发,都需要了解一点它的知识. 本文详细介绍DNS的原理,以及如何运用工具软件观察它的运作.我的目标是,读完此文后,你就能完全理解DNS. 一.D ...

  6. linux expr命令参数及用法详解

    expr用法 expr命令一般用于整数值,但也可用于字符串.一般格式为: #expr argument operator argument expr也是一个手工命令行计数器. #$expr 10 + ...

  7. 实战WEB 服务器(JAVA编写WEB服务器)

    实战WEB 服务器(JAVA编写WEB服务器) 标签: web服务服务器javawebsockethttp服务器 2010-04-21 17:09 11631人阅读 评论(24) 收藏 举报  分类: ...

  8. JavaScript(四)---- 函数

    函数主要用来封装具体的功能代码. 函数是由这样的方式进行声明的:关键字 function.函数名.一组参数,以及置于括号中的待执行代码. 格式: function 函数名(形参列表){         ...

  9. 【啊哈!算法】算法7:Dijkstra最短路算法

    上周我们介绍了神奇的只有五行的Floyd最短路算法,它可以方便的求得任意两点的最短路径,这称为“多源最短路”.本周来来介绍指定一个点(源点)到其余各个顶点的最短路径,也叫做“单源最短路径”.例如求下图 ...

  10. 解决adb端口被占用的方法

    错误: [2016-04-20 19:05:04 - ddms] 'E:\android\android-sdk\android-sdk\platform-tools\adb.exe,start-se ...