热门:网页模板.net视频教程JQueryMVCjsonExtJs源码示例三级联动JQuery菜单
您现在的位置:.Net中文社区>> .Net编程>>正文内容

ViewState—又见ViewState

发布时间:2008年12月22日点击数: Frog
示例代码

最近看见有朋友说Page_Init只执行一次,我始终将信将疑,于是自己测试一下,结果发现在每次单击按钮的时候还真的不会再增加Init这样的列表项了。难道Page_Init还真的是只执行一次么?空想也不是解决办法,打个断点跟踪下吧,发现每次回发时Init是会执行的,由此可见出现这种情况是和Init无关的(她是无辜的)。真正的幕后'黑手'又会是谁呢?

一、页面生命周期

     一个ASP.NET页面大致可以分为一下几个阶段:

     1,因为它也是一个类,所以构造函数是必定首当其冲的,不过我们一般很少会用到它。

     2,初始化阶段。在这个阶段,asp.net为我们细化了三个方法:Page_PreInit,Page_Init,Page_InitComplete,他们的方法签名和Page_Load完全一样,全是 void Page_XXX( object sender, EventArgs e )..的形式。而方法名称也都是固定的(这些可以通过查看TemplateControl源码看到)。

     3,Load阶段。这个阶段我们可以通过这几个方法来对页面进行控制:Page_PreLoad,Page_LoadComplete,Page_Load。

     4,如果有定义了引起回发的控件的相应事件处理程序(比如按钮,点击后引起回发,这时如果你在后台定义了该按钮的Click事件处理程序),则执行该事件处理程序(会在Page_LoadComplete执行前执行)。

     5,呈现。同样,有这样几个方法:Page_PreRender,Page_PreRenderComplete,Render。

     6,卸载页面,释放资源:Page_Unload

     注:这些方法和相应的事件绑定是通过在aspx页面的@Page指令里设置AutoEventWireup="true"来完成的。如果去掉这个属性,则这些方法将不再发挥作用。

     下面看个小例子:

点击展开示例

执行的结果如下: 

(注:相对于Controls.Add的方式我更倾向于使用Form.Controls.Add。因为查看生成的页面的源码发现新添加的控件跑到了html结束标签的后面。)

二、寻找'黑手'

     上面简单的介绍了页面的生命周期,下面就让我们来寻找造成前面问题的'凶手'吧。其实从文章题目大家也基本上可以猜测到我想说'凶手'其实就是ViewState。

     说到ViewState就必须要提及与它息息相关的三个方法:LoadViewState,SaveViewState,TrackViewState。

     先看下这三个方法会出现在页面生命周期的哪个部分呢,还是看代码吧:

点击展开.aspx示例

 

点击展开.cs示例

结果如下:

1.在页面第一次加载时:

2.点击按钮产生回发时:

可以发现在回发时多了一个LoadViewState,它做了什么事情呢?它的工作就是从页面的_ViewState隐藏域中恢复视图状态。那在这个阶段之前对视图状态的更改呢?结果是将会被覆盖掉。于是对应于我们的DropDownList的例子,当第一次执行时为其动态添加的两个item都将被放到视图状态中(通过SaveViewState),而在产生回发时,尽管在执行到Init时又添加了Item,到了LoadViewState的时候,DropDownList的Items又会恢复成上一次保存到视图状态时的情形(同时接下来在调用SaveViewState方法时,又会将当前的Items放到视图状态中去)。如此反复,也就难怪只能看见一直增加Load这样的Item了。

三、为ViewState正名

     郑重声明,ViewState是个好人。

本站热点业务

更多模板/案例展示

关于我们 | 联系我们 | 团队日志 | 网站地图 | 网站合作