代码讨论
IndexButton 控件的实现阐释了三个任务,必须执行这三个任务才能使控件参与控件状态:
· 重写 OnInit 方法并调用 RegisterRequiresControlState 方法向页面注册,以参与控件状态。必须针对每个请求完成此任务。
· 重写 SaveControlState 方法,以在控件状态中保存数据。
· 重写 LoadControlState 方法,以从控件状态加载数据。此方法调用基类方法,并获取基类对控件状态的基值。如果 indexValue 字段不为零,而且基类的控件状态也不为空,Pair 类便可作为方便的数据结构使用,用来保存和还原由两部分组成的控件状态。
分析总结
从MSDN上的一系列的技术参考来看,ControlState应该是主要在自定义控件上使用,“ASP.NET 页框架提供了 ControlState 属性作为在服务器往返过程中存储自定义控件数据的方法”,这是MSDN上的原句,ASP.NET2.0只是为ControlState提供了一个基础,当 ControlState是一个自定义的状态保持机制,也就是说保持状态的机制需要你开发人员自己去完成,而不像ViewState,它有自己默认的状态保持机制。在自定义控件使用ControlState也许才是微软本意了,为的就避免在页面级别禁用掉ViewState后,自定义控件还能正常运行。当然这里的意思就是,某些控件的正确运行是依赖于它的状态信息的,在ASP.NET1.1中,如果禁用了ViewState,这样的控件就无法正确运行了。但引入了ControlState后就不同了,因为ControlState是禁用不掉的。
所以微软才提醒开发人员“请仅对那些在回发过程中对控件至关重要的少量关键数据使用控件状态,而不要将控件状态作为视图状态的备用选项使用”。明确说出,ControlState和 ViewState完全是两个东西,虽然它们可以完成相同的任务,新推出的ControlState既不是用来替代ViewState也不是用来做 ViewState的替补。它的使命是弥补ViewState的所不能完成的任务,让开发人员开发出更加健壮的控件。例如说,开发的自定义控件某个状态是至关重要的,缺少它就自定义控件不能正常工作,那么ControlState就该上场了。而且ControlState是自定义的状态保持机制,也限制了 ControlState自由的使用,你不但要在OnInit 方法并调用 RegisterRequiresControlState 方法向页面注册,而且要重写SaveAdapterControlState(),LoadAdapterControlState(object state)两个方法自己去实现要保存什么,怎样保存。根据我现在的理解,如果你需要保存该控件的10种不同状态,那你就得一一保存,再一一加载上去。从这点也就看出了微软的初衷了,那不是很明显吗,如果不需要ControlState那就不使用它吧,否则怎么它什么都让我们开发人员去做呢?
这只是基础了,刚才我说了,似乎微软也是这么说的,ControlState针对的是自定义控件,其实我们真的要去开启基本控件例如Label 控件的ControlState,微软也是允许的,这就是稍深的内容了,这就涉及到控件适配器了(ControlAdapter)。如果需要了解这方面的内容,请看用控件适配器开启基本控件的ControlState。http://sifang2004.cnblogs.com/archive/2006/06/01/415288.html
附录
为了更加充分理解上面的内容,需要对以下内容有个了解:
Pair 类
用作存储两个相关对象的基本结构。它是在整个 ASP.NET 中(在如页面状态管理任务期间或配置节处理程序的过程中)有多种用法的实用工具类。可以在自己的代码中需要包含两个相关对象的结构的任意位置和不一定需要数据绑定的位置使用 Pair 类。Pair 类不将其对象引用 First 和 Second 封装在属性中;该类直接将它们作为公共类字段公开到所有调用代码。
Pair 类在页状态保留实现中有多种用法。最常见的用法是同时作为 ViewState 和 ControlState 集合的容器。在这种情况下,First 属性用于 ViewState,而 Second 用于 ControlState。
PageStatePersister 类
HTTP 请求和响应原本是无状态的。要在 HTTP 请求之间保持状态信息,ASP.NET 服务器页可以存储 Page 状态。此状态称为视图状态,它包含页和控件设置及数据,这些设置和数据使得页和控件看起来就像在上一次将它们提交到服务器然后又返回到客户端时,用户所看到并与之交互的页和控件一样。有几种机制可在对相同页的连续请求之间存储视图状态。PageStatePersister 抽象类表示这些状态信息存储机制的基类。
要在不能支持现有视图状态持久性机制的客户端上保留视图状态,可以扩展 PageStatePersister 类,引入您自己的视图状态持久性方法,并且可以使用页适配器将 ASP.NET 应用程序配置为根据为其提供页的客户端的类型使用不同的视图状态持久性机制。从 PageStatePersister 类派生的类必须重写 Save 抽象方法,以便在持久性介质中存储视图状态和控件状态,同时重写 Load 方法以提取状态信息。如果想知道如何写PageStatePersister的派生类,请参考视图状态持久性机制。