理解C#中的事件:模拟C#中按钮事件的触发过程
平日里做开发,在对一个按钮点击后的逻辑进行编码时,我们得助于VS强大的功能,只要双击按钮,在代码中就会自动生成时间方法,然后我们只要在生成方法如:
{
//TO DO
}
我们只要在TO DO 这里写好自己的逻辑即可。相信大多人也会用button1.Click+=new EventHandle(button1_Click)来给按钮绑定事件方法。
现在我想自己写一个Demo来模拟这个过程,并且希望能够加深对按钮事件触发的理解,顺便也熟悉.net的事件模型。
using System.Collections.Generic;
using System.Text;
namespace EventDemo
{
///<summary>
/// 事件委托
///</summary>
///<param name="sender"></param>
///<param name="e"></param>
publicdelegatevoid EventHandle(object sender, EventArgs e);
class Program
{
staticvoid Main(string[] args)
{
Button btn =new Button();
btn.Click +=new EventHandle(btn_Click);
Trigger(btn,EventArgs.Empty);//相当于鼠标点击触发
Console.Read();
}
staticvoid btn_Click(object sender, EventArgs e)
{
Button btn = (Button)sender;
btn.Text ="我被点击了";
Console.WriteLine(btn.Text);
}
///<summary>
/// 用户单击了窗体中的按钮后,Windows就会给按钮消息处理程序(WndPro)发送一个WM_MOUSECLICK消息
///</summary>
///<param name="btn"></param>
///<param name="e"></param>
staticvoid Trigger(Button btn, EventArgs e)
{
btn.OnClick(e);
}
}
///<summary>
/// 模拟Button
///</summary>
publicclass Button
{
privatestring txt;
publicstring Text
{
get { return txt; }
set { txt = value; }
}
publicevent EventHandle Click;//定义按钮点击时间
///<summary>
/// 事件执行方法
///</summary>
///<param name="sender"></param>
///<param name="e"></param>
void ActionEvent(object sender, EventArgs e)
{
if (Click ==null)
Click +=new EventHandle(Err_ActionEvent);
Click(sender, e);//这一部执行了Program中的btn_Click方法
}
void Err_ActionEvent(object sender, EventArgs e)
{
thrownew Exception("The method or operation is not implemented.");
}
publicvoid OnClick(EventArgs e)
{
ActionEvent(this, e);
}
}
}
以上是模拟我们点击鼠标,然后执行事件函数的整个过程。
用户单击了窗体中的按钮后,Windows就会给按钮消息处理程序(WndPro)发送一个WM_MOUSECLICK消息,对于.NET开发人员来说,就是按钮的OnClick事件。
从客户的角度讨论事件:
事件接收器是指在发生某些事情时被通知的任何应用程序、对象或组件(在上面的Demo中可以理解为Button类的实例btn)。有事件接收器就有事件发送器。发送器的作用就是引发事件。发送器可以是应用程序中的另一个对象或者程序集(在上面的Demo中可以理解为程序集中的program引发事件),实际在系统事件中,例如鼠标单击或键盘按键,发送器就是.NET运行库。注意,事件的发送器并不知道接收器是谁。这就使得事件非常有用。
现在,在事件接收器的某个地方有一个方法(在Demo中位OnClick),它负责处理事件。在每次发生已注册的事件时执行事件处理程序(btn_Click)。此时就要用到委托了。由于发送器对接收器一无所知,所以无法设置两者之间的引用类型,而是使用委托作为中介,发送器定义接收器要使用的委托,接受器将事件处理程序注册到事件中,接受事件处理程序的过程成为封装事件。
[参考:红皮书第四版C#高级编程]