`

事件注册

    博客分类:
  • C#
 
阅读更多

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

我们可以看到如下代码:

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

实际上这段代码,也就是所谓的事件注册代码。该代码的意思是:如果this.button1的Click事件发生之后,就转向this. button1_Click方法进行处理。

为了更好的理解事件的注册过程,我们先第42行代码进行修改,如下图所示:

这里,我们将原来的

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

修改为

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

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

下面我们对其进行分析:

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

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:

shenqiboy
分享到:
评论

相关推荐

    LabVIEW的动态事件注册

    动态事件注册可完全控制LabVIEW产生的事件的类型和时间。动态事件可使事件仅在应用程序的某个部分发生,也可在应用程序运行时改变产生事件的VI或控件。使用动态注册,可在子VI中处理事件而不是仅在产生事件的VI中...

    C# 事件中心,一个简单的事件注册调用管理功能

    在这个简单的事件注册调用管理功能中,我们可以看到如何在C#中有效地实现这一模式。 首先,事件的基本组成部分包括事件发布者(Event Publisher)、事件订阅者(Event Subscriber)和事件(Event)。发布者拥有事件...

    继承、虚函数的应用模式(二):事件注册与调度机制

    本文将深入探讨如何利用这些概念来设计和实现事件注册与调度机制,这是一种常见于软件工程中的设计模式,特别是对于事件驱动或异步编程的场景。 继承允许一个类(子类)继承另一个类(基类)的属性和行为,这样可以...

    事件注册实现界面数据交互

    在软件开发中,尤其是UI设计和用户交互部分,事件注册是实现界面数据交互的一种常见方法。事件通知机制允许不同组件之间进行通信,而无需直接耦合。本文将深入探讨事件注册的概念,以及如何通过事件通知来实现界面间...

    Flowable 6.6.0 事件注册用户指南.pdf

    在介绍Flowable 6.6.0版本的事件注册用户指南时,文档提供了关于事件注册引擎的概念、配置、API接口以及与Spring框架的集成方法。下面详细解释各个知识点。 1. 事件注册介绍: 1.1 事件注册是指什么? 事件注册...

    vue20的touch事件原生事件注册无依赖体积小1K

    标题中的"vue20的touch事件原生事件注册无依赖体积小1K"意味着我们将讨论一个专注于在Vue 2.0中使用触摸事件的方法,该方法不仅直接利用了JavaScript的原生事件,而且实现了轻量化,整个插件或解决方案的体积小于1KB...

    按键状态机+事件注册回调处理驱动demo

    "按键状态机+事件注册回调处理驱动demo"是一个典型的实现方式,它结合了状态机的概念以及事件回调机制来高效地管理按键操作。下面我们将详细探讨这两个核心概念。 1. **按键状态机**: 状态机是一种用于描述系统...

    继承、虚函数的应用模式:事件注册与调度机制

    事件注册与调度机制是利用这些概念来实现的一种常见设计模式,尤其是在开发事件驱动的软件系统时。下面我们将深入探讨这个主题。 首先,**继承**允许一个类(子类)继承另一个类(父类)的属性和行为。在C++中,...

    将全局事件注册为组件

    这个“将全局事件注册为组件”的主题主要涉及Vue.js的实例属性、事件监听与触发,以及如何通过自定义事件来实现组件间的通信。下面将详细解释这些概念。 首先,Vue.js中的组件是可复用的代码块,每个组件都有自己的...

    js闭包引起的事件注册问题介绍

    本文将探讨在事件注册中,如何由于闭包的特性导致了一个常见的问题,并通过实例来解析这个问题的原因。 首先,让我们回顾一下问题的代码片段: ```javascript function pageLoad() { for (var i = 1; i ; i++) { ...

    分析js闭包引起的事件注册问题

    标题中提到的“js闭包”和“事件注册问题”是两个核心概念。闭包是JavaScript中的一个高级特性,指的是函数能够记住并访问所在词法作用域,即使函数是在当前词法作用域之外执行。事件注册问题则是指在JavaScript中...

    ERS:一个基于网络的事件注册系统-开源

    **事件注册系统(ERS):基于Web的开源解决方案** 事件注册系统(ERS)是一个创新的解决方案,旨在通过网络提供高效、便捷的事件管理服务。作为一款开源软件,ERS为用户提供了透明度、灵活性以及无限的定制可能性,使得...

    Unity-利用Action和Func注册事件

    利用Action和Func来简化事件的注册过程!!!!!!!!

    UnityNGUI事件自动注册代码生成

    `Packages`则用于管理Unity Package Manager中的第三方库和插件,可能是用来引入这个自动事件注册功能所需的外部组件。 总之,这个项目旨在通过自定义的编辑器工具提升Unity NGUI的事件处理效率,让开发者可以更...

    EDA/PLD中的LabVIEW的动态事件注册

    动态事件注册可完全控制LabVIEW产生的事件的类型和时间。动态事件可使事件仅在应用程序的某个部分发生,也可在应用程序运行时改变产生事件的VI或控件。使用动态注册,可在子VI中处理事件而不是仅在产生事件的VI中...

    LabVIEW的静态事件注册

    用户界面事件可以进行用户静态事件注册,使用“编辑事件”对话框配置事件结构来处理静态注册的事件。选择事件源,事件源可以是程序、VI或某个控件;再选择一个事件源可产生的特定事件,如前面板大小调整,值改变等,...

    多次注册事件会导致一个事件被触发多次的解决方法

    在编写JavaScript代码时,理解事件注册机制以及如何有效地管理事件绑定是至关重要的。为了避免类似的问题,可以遵循以下最佳实践: 1. **使用条件检查**:如上面的例子所示,检查事件是否已经绑定,只有未绑定时才...

    goer:goer-简单的golanghr事件注册应用程序

    goer-简单的golanghr事件注册应用程序 工作正在进行中... 去做 基本特征 带有以下字段的表单提交:姓名,姓氏,电子邮件 事件描述 确认电子邮件(您已经注册,这是基本的活动信息,所以请不要忘记) 活动地点 将...

    init.c轮询注册事件

    1. **事件注册**:首先,在`init.c`中定义一个全局变量(如链表)用于存储所有注册的USB设备初始化回调函数。 2. **轮询检查**:接着,在内核初始化过程中,定期检查USB总线上的设备列表是否有新设备接入。如果没有...

    labview动态注册事件

    在LabVIEW中,“动态注册事件”是一项核心功能,它允许用户在运行时注册事件处理程序,极大地提高了程序的灵活性和可扩展性。下面将详细阐述这一知识点。 一、事件驱动编程模型 LabVIEW采用事件驱动编程模型,这...

Global site tag (gtag.js) - Google Analytics