c#中委托、事件之我见(二)

在本节中,主要讲对c#中事件的理解。

一、Windows消息

提到事件,就不能不提到windows消息,先简单的回顾一下windows消息传递机制:windows消息服务就是一监听程序,当点击鼠标或者按下键盘键,监听程序都将捕获该事件,并作为windows消息进入windows消息队列,windows根据消息的Message ID将各个消息派发给对应的处理程序(当然,也会将没有对应处理程序的消息丢弃)。比如,在点击了某个窗体上的一个按钮,windows最终会将该点击事件消息传递给该按钮的点击事件处理程序(按钮也是一个独立的窗体,窗体建立的时候都会想操作系统Register)。

二、事件处理过程模拟

理解了以上基础,在言归正传。以Button为例。

首先,Button也是一个类(这一点很重要,一般对于很抽象的概念,看到本质很重要),那么当Button类的实例接收到这一点击事件的消息时,在该类中肯定定义了一个对应的处理函数。不妨将Button想象成如下样子:

public class Button

    {

        //...................

        private void ClickEventMethod()

        {

            //.......

        }

        //..................

}

该类定义了ClickEventMethod方法来处理按钮点击事件,有问题么,呵呵,估计都发现了,处理过程代码都在内部写死在,程序员还做什么。

熟悉C++的朋友可能都想到了,在该类中不写ClickEventMethod函数的实现,仅仅定义一个public型函数指针,把实现函数留给程序员去写,同时程序员负责在程序中把实现函数关联到此函数指针上。不妨再将Button想象成如下样子:

按钮(Button)类

public class Button

    {

        //C#没有指针概念,这里先借用一下C++语法,

//这里只要知道fpClickEventMethod是一个函数指针,指向点击事件的处理函数就可以了

        void (*fpClickEventMethod)();

        //..................

}

 

同时在放有该Button按钮的窗体类中添加如下的代码

public partial class DelegateTest : Form

     {

        //...............

        this.btnButton.fpClickEventMethod = ClickEventMethod;

 

        private void ClickEventMethod()

        {

            //..............

        }

        //................

}

好,问题解决了,当点击按钮事件传到到Button窗体时,该类对象找到fpClickEventMethod函数指针指向的函数并调用,最终的处理程序(ClickEventMethod实现)完全在程序员的控制下。

可是c#中并没有函数指针这东东,怎么办。我们在前面一节中讲的委托很好的解决了这个问题。

三、委托实现事件处理,函数回调。

新建一窗体,取名叫frmTest,在窗体上放一NamebtnTest的按钮,双击按钮,frmTest.cs代码如下:

    public partial class frmTest : Form

    {

       //................

        private void btnTest_Click(object sender, EventArgs e)

        {

        }

}

frmTestDesigner.cs代码如下:

partial class frmTest

    {

        private void InitializeComponent()

        {

            this.btnTest = new System.Windows.Forms.Button();

            this.btnTest.Click += new System.EventHandler(this.btnTest_Click);

            //................

        }

       //................

}

两个单元合并成了一个完整的frmTest类,点击事件的实现函数在frmTest.cs中,定义如下:

private void btnTest_Click(object sender, EventArgs e)

该实现函数通过frmTestDesigner.cs中的如下语句绑定在一个叫Click的东东上。

this.btnTest.Click += new System.EventHandler(this.btnTest_Click)

Click上点右键选择“转到定义”,看到如下代码:

public event EventHandler Click

这里EventHandler是什么东东,继续在EventHandler点右键选择“转到定义”,看到如下代码:

public delegate void EventHandler(object sender, EventArgs e)

到这里,终于真相大白,原来EventHandler是一个委托类,在Button中定义了该委托类的一个对象变量Click(可以理解成函数指针),该委托最终绑定到btnTest_Click(object sender, EventArgs e)函数上。当按钮接收到点击事情消息时,转到Click委托,最终找到Click委托指向的的btnTest_Click处理函数。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值