您的位置:首页 > 其它

[Joe 原创] Web Control 开发系列(二) 深入解析Page的PostBack过程和IPostBackDataHandler

2012-05-06 09:39 501 查看
[Joe 原创] Web Control 开发系列(二) 深入解析Page的PostBack过程和IPostBackDataHandler
IPostBackDataHandler和IPostBackEventHandler对于实现一个WebControl是非常重要的,如果你的 Contro仅仅是readonly的,也就是说不会让客户端进行输入和修改,那么这两个接口就没有用,一旦你要和客户端交互,那么这两个接口是必须掌握的。IPostBackDataHandler可以让你的Control和客户端的输入数据进行交互,比如TextBox,CheckBox,而 IPostBackEventHandler可以让你的Control和客户端的动作行为进行交互,比如Button(click行为)。如果你既希望接收客户端的数据,也希望接收客户端的行为,那么就要同时实现这两个接口了。 在我的上一篇文章《页面的生命周期》里面,我详细介绍了页面生存周期的各个阶段,但是对于PostBack阶段介绍的并不是很多,在本文里面我将详细补充介绍页面生存周期的PostBack 阶段,因为IPostBackDataHandler,IPostBackEventHandler仅仅发生在页面生存周期的PostBack阶段。其实我们可以在PostBack做很多的事情,.net Framework认为大多数用户都希望处理Post回来的数据和事件,所以基于这个目的,他们为我们设计了IPostBackDataHandler和 IPostBackEventHandler这两个接口,这仅仅是微软的一个设计,所以没有什么特别神秘的。我们只要很好的理解他们的设计,就能让我们的 Control无缝的和所有基于.net Framework实现的其它Control协同工作。下面我将一步一步分析这两个接口的实现。
一、Page是什么? 当在Visual Stdio里面new一个Page的时候,生成的代码如下:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>Untitled Page</title> </head> <body> <form id="form1" runat="server"> <div> </div> </form> </body> </html>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><title> Untitled Page </title></head> <body> <form name="form1" method="post" action="Default.aspx" id="form1"> <div> <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUJNzgzNDMwNTMzZGQP0LJECgTtp1lOdVaW3IZPFDdsYw=="/> </div> <div> </div> </form> </body> </html>
// 1. PreInit this.PerformPreInit(); // 2. Init this.InitRecursive(null); this.OnInitComplete(EventArgs.Empty); // 对于Postback,插入下面处理 if (this.IsPostBack) // 3. PreLoad this.OnPreLoad(EventArgs.Empty); // 4. Load this.LoadRecursive(); // 对于Postback,插入下面处理 if (this.IsPostBack) this.OnLoadComplete(EventArgs.Empty);
privatevoid ProcessPostData(NameValueCollection postData, bool fBeforeLoad) privatevoid SaveAllState() { if (this._needToPersistViewState) { // 1. 把ControlState存储到dictionary里面 . // 2. 把注册的需要PostBack处理的Control的id集合加入到用来保存ControlState // 的dictionary里面 if ((this._registeredControlsThatRequirePostBack !=null) && (this._registeredControlsThatRequirePostBack.Count >0x0)) { dictionary.Add("__ControlsRequirePostBackKey__", this._registeredControlsThatRequirePostBack); } // 3. 收集ViewState . // 4. 把所有的State序列化到Page页面的hidden字段 . } }



通过上面的代码,我这里做一个小结:如果要写一个实现IPostBackDataHandler的Control,除了实现接口本身外,还必须做到下面两种方法的一种,才可以顺利完成任务: 第一种:该Control Render出来的元素本身就是一个表单域(form field),而且表单域的name和control的id保持一致,这样,Page在拿到表单域的数据后,可以通过name调用FindControl来找到相应的Control,然后如果Control.PostBackDataHandler 不为null,就进入调用入口。 第二种:该Control存放数据的表单域的name和该control的id并没有对应的关系,所以就需要在PreRender的时候(也可以在其它阶段,如Load等,不过大部分是在PreRender里面做),调用Page.RegisterRequiresPostBack(Control control) 方法,传入this作为参数,这样也可以保证Page会遍历所有注册过的Control,然后进入IPostBackDataHandler的调用入口。 综上所述,PostBackData,就是在客户端的一个数据缓存,当用户在客户端修改的时候,都是修改的数据缓存,不会和服务器通信,只有当form submit的时候,一次PostBack发生,然后缓存的数据会被form收集并传输到服务器端,服务器端就调用IPostBackDataHandler来处理传回的数据。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐