Saturday 30 June 2007

DataGrid中Button的Click事件如何最后会Call到DataGrid的ItemCommand处理函数

这几天在阅读别人的代码,用的最多的是DataGrid控件,而且经常用ItemCommand事件来处理Button的OnClick事件,但是为什么Button的Click事件最后会调用到DataGrid的ItemCommand事件处理函数呢?于是就开始去探索Button的Click事件的处理流程。在探索的过程中,使用了Lutz Roeder's .NET Reflector工具。

对于所有希望处理PostBack Event的控件都需要Impement IPostBackEventHandler接口,这个接口只有一个方法,那就是RaisePostBackEvent,Button类有Implement这个接口,下面是它的代码:




它调用了自身的RaisePostBackEvent函数,我们来看看它做了些什么:



我们看到最后两行直接调用OnClick和OnCommand函数,OnClick函数没有什么,只是对所有注册的Handler进行调用,但是OnCommand的函数有点不同:


前面部分和OnClick处理函数很类似,但是它多了最后一行: base.RaiseBubbleEvent(this, e); 这个函数到底做了什么呢?我们去看看它的代码(在System.Web.UI.Control类中):


代码很简单,只是对当前控件的父控件一个一个的调用OnBubbleEvent函数,当有人处理的时候,整个过程就结束。

那么当Button放在DataGrid中的时候,首先的父控件是DataGridItem,我们看看DataGridItem的OnBubbleEvent做了什么:



这个函数只是对Command事件做出一些修改,首先把CommandEventArgs改成DataGridCommandEventArgs,然后还是调用base.RaiseBubbleEvent函数(还是System.Web.UI.Control类)。接着追DataGridItem的父控件--DataGrid。

因为代码有点长,所以没有列出来,但是它首先就调用OnItemCommand函数,然后对内置的一些Command做出处理。这就揭开了为什么Button的Click事件会最后调用到DataGrid的ItemCommand处理函数。

No comments: