在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
想一下,如果页面视图没有禁用时该多好,可以以this.ViewState["Text"]的格式直接使用Control中的ViewState对象,非常方便。既然 ViewState对象不管禁用还是不禁用都在Control类中是存在的,那不用它岂不浪费。这一节主要内容就是如何实现在禁用视图状态下仍然可以使用 ViewState对象。 该功能在主控件ControlStateControl中已经实现了。回顾一下主控件的代码片段: /// /// 获得本书更多内容,请看: /// http://blog.csdn.net/ChengKing/archive/2008/08/18/2792440.aspx /// public class ControlStateControl : WebControl { //… … [Description("使用ViewState属性来存储数据此属性")] public string Text_ViewState { get { String s = (String)ViewState["Text_ViewState"]; return ((s == null) ? String.Empty : s); } set { ViewState["Text_ViewState"] = value; } } //… … protected override object SaveControlState() { Pair p = new Pair(); p.First = base.SaveViewState(); p.Second = ((IStateManager)FaceStyle).SaveViewState(); //… … return p; } protected override void LoadControlState(object savedState) { if (savedState == null) { base.LoadViewState(null); return; } else { //… … base.LoadViewState(p.First); //… … } } //… … } 在ControlStateControl中,属性Text_ViewState仍然存储在基类Control的ViewState对象中,且运行页面中同时禁用了页面和控件视图状态,但该属性仍然能够正确地应用视图状态。 在视图状态启用状态下,在LoadViewState方法中会默认调用基类的base.LoadViewState方法,其中就包含对基类中ViewState对象进行对象序列化的代码,如下: protected virtual void LoadViewState(object savedState) { if (savedState != null) { this.ViewState.LoadViewState(savedState); object obj2 = this.ViewState["Visible"]; if (obj2 != null) { if (!((bool)obj2)) { this.flags.Set(0x10); } else { this.flags.Clear(0x10); } this.flags.Set(0x20); } } } 其中这句this.ViewState.LoadViewState(savedState)为关键语句,还记得ViewState属性实际的类型为StateBag类,它是系统定义的类型视图状态实现类(我们在6.2.3小节探讨过)。 同样在,SaveViewState方法中也有序列化保存ViewState属性对象的代码,如下所示: protected virtual object SaveViewState() { if (this.flags[0x20]) { this.ViewState["Visible"] = !this.flags[0x10]; } if (this._viewState != null) { return this._viewState.SaveViewState(); } return null; } 关键语句为this._viewState.SaveViewState(),ViewState是对外属性,其操作的变量就是StateBag类型的_viewState。 在视图状态被禁用的情况下,由于LoadViewState和SaveViewState不再被页框架调用(默认情况下是base.SaveViewState和base.LoadViewState方法不会再被调用),所以ViewState属性功能也就失效。 了解了ViewState对象的来龙去脉,现在就讲解一下在ControlStateControl控件中仍然可以使用ViewState的原因。在 LoadControlState和SaveControlState方法中分别调用base.LoadViewState和 base.SaveControlState,我们可以手动调用ViewState属性对象的对象正反序列化过程。归根到底,也就是说开发人员所谓的禁用视图实际上是禁止LoadViewState和SaveViewState两个方法的执行,但理论上我们只要启动控件状态,并把这两个方法的逻辑放到 LoadControlState和SaveControlState中,仍然可以利用ViewState。 本节内容有些乖张,违反了 ASP.NET设计页面状态的规则。既然ASP.NET框架把视图和控件状态已经分开了,建议在实际开发中分开处理,不要滥用。在 LoadControlState方法中尽量只写控件状态相关逻辑,在LoadViewState中只写视图状态相关逻辑,毕竟ControlState 是专门为存储控件必需的少量数据设计的。不过上面在ControlState中使用ViewState的确是非常方便的,在处理基本类型的属性时能够节省开发时间。 |
请发表评论