大家已经在知道在我们开发ASPNET网站的时候每个服务器控件都有自己的ID为了后面更好的展开下面我们就来简单的看看这个场景当我们在浏览器中点击了一个服务器控件如 Button此时页面回传给服务器然后服务器就引发控件的Click等事件这个场景是简单的不能在简单了
我们来进一步看我们知道不是所有的控件都会在服务器端触发事件的比如 submit按钮这个按钮也同样可以把表单数据传到服务器但是这个控件不能在服务器端触发事件其实在一个页面提交到了服务器之后服务器就会检查是哪个控件引起了页面提交然后就把这个控件的ID找到然后再在我们请求的那个页面如Defaultaspx (假设我们点击按钮请求的是Defaultaspx)去找是否有服务器控件的ID和此时提交页面的ID是一样的如果有那么就在页面的生命周期的合适的时候引发事件在把处理的结果返回如果没有服务器就不做什么了特别的处理
还有一点要注意的是在查找那个控件的ID 的时候页面(如Defaultaspx)已经被编译成为了一个继承自Page的类
当然上面说的只是一个很粗略额过程希望大家有个总体的认识下面就细致的讲解
我通过一个流程来解释
我们首先请求一个服务器端的页面如x为了方便解释假设页面只有三个服务器控件TextBoxDropDowmListButton
定义如下
<%@ Page Language=C# %>
<!DOCTYPE html PUBLIC //WC//DTD XHTML Transitional//EN transitionaldtd>
<html xmlns=>
<head runat=server>
<title>Untitled Page</title>
</head>
<body>
<form id=form runat=server>
<asp:TextBox runat=server ID=TextBox />
<asp:DropDownList runat=server ID=DropDownList>
<asp:ListItem Text=Text Value=Value />
<asp:ListItem Text=Text Value=Value />
<asp:ListItem Text=Text Value=Value />
</asp:DropDownList>
<asp:Button runat=server Text=Submit />
</form>
</body>
</html>
在浏览器中我们在源中看到的如下
<!DOCTYPE html PUBLIC //WC//DTD XHTML Transitional//EN
transitionaldtd>
<html xmlns=>
<head>
<title>Untitled Page </title>
</head>
<body>
<form name=form method=post action=Defaultaspx id=form>
<div>
<input type=hidden name=__VIEWSTATE id=__VIEWSTATE
value=/wEPDwUKMTAxNzkMjYOWRkxj+HeOcNxVutpxOdaSpw= />
</div>
<input name=TextBox type=text id=TextBox />
<select name=DropDownList id=DropDownList>
<option value=Value>Text</option>
<option value=Value>Text</option>
<option value=Value>Text</option>
</select>
<input type=submit name=ctl value=Submit />
</form>
</body>
</html>
确实上面的那些HTML的代码确实没有什么但是大家注意看看TextBoxDropDownList它们的ID在服务器端的aspx页面和本地的源中的ID是一样的
我们在浏览器中的TextBox中输入xiaoyang然后DropDowList 选中Text然后我们点击按钮提交此时我们提交的数据被包含在表单中的而且是以这样的格式保存的TextBox=xiaoyang&DropDownList=Value不用多说表单数据是用&来分隔的而且每个分隔的串包含两个部分ID和值也就是键值对
数据到了服务器后ASPNET就实例化一个 HttpRequest的类这个类有两个属性 Forms和 QueryString它们的类型都是NameValueCollection(键值对大家可以把它看成一个HashTable)然后ASPNET解析表单数据表单数据就解析成为了一个个的键值对然后就保存在Forms(POST提交)或者QueryString中(GET提交)我们之前是以POST提交为例子的
之前的事情是发生在页面的生命周期之前的当页面调用自己的ProcessRequest方法后就进入了页面生命周期此时页面就会检查页面中的所有控件看看它们有哪些实现了IPostBackDataHandler接口然后把实现了这些接口的控件都放入到一个ArrayList中然后也检查哪些控件实现了IPostBackEventHandler也把它们假如到另外的集合中之后就开发遍历实现了IPostBackDataHandler控件的集合并且调用IPostBackDataHandler的方法LoadPostData(string postdatakeyNameValueCollection value)
之前说过了的我们提交的表单的值都保存在了Forms中(它的类型是NameValueCollection 的)所以此时这些值就传入到了这个方法然后就检查这些值和之前的是不是相同的我们已经还记得我们在浏览器中看到页面时页面中的TextBox 初始时是没有值的而且DropDownList选择的是Text现在我们的值改了是xiaoyang和Text所以这个方法检查的结果是值变了返回了true只要返回了true那么IPostBackDataHandler的下一个方法就会调用RaisePostDataChangeEvent()这个方法已经注册了事件到页面生命周期的之后就后引发的
所以如果我们开发的自定义控件想要在数据改变的时候引发事件那么就一定要实现IPostBackDataHandler接口例子可以参看我的另外的控件开发的系列文章
现在我们已经说到了数据的改变下面就看看到底是怎么引发事件的到了页面开发执行RaisePostbackEvent方法的时候页面就会遍历实现了IPostBackEventHandler的控件的集合并且检查是否在页面中存在一个控件这个控件要实现了IPostBackEventHandler并且ID和之前使得页面提交到服务器的的那个控件的ID一样如果有IPostBackEventHandler的RaisePostBackEvent 方法来触发事件(不同控件实现这个方法的方式不同)如Click事件
所以如果想在自定义控件可以触发事件那么就要实现IPostBackEventHandler接口可以参看我的控件开发系列文章有例子的
今天到这里!谢谢大家