如何通过ViewState为ASP.NET中的子控件保留数据?

时间:2010-03-03 20:27:17

标签: c# asp.net viewstate onload onpreinit

我有一个控件(比如,一个DataGrid或一个ComboBox),它是用户控件的子代。我想在每个请求上使用DataBind,而不是让它的状态通过ViewState持久化。我需要离开EnableViewState=true。我认为这意味着我需要在调用TrackViewState()之前调用DataBind。

我阅读了精彩的博文TRULY Understanding ViewState,并在4. Initializing child controls programmatically中回答了我的问题。然而,文章的解决方案并不理想:动态创建子控件(我不是也不能 - 现有代码太多),使用第三方CodeExpressionBuilder(更喜欢这是代码隐藏),并使用OnPreInit(如果你正在开发一个CONTROL,它“对你没有任何帮助”)。

由于那篇文章相当陈旧(大约在2006年),我希望更新版本的ASP.NET能够纠正这种情况,以便现在有更好的解决方案。那么,社区,有什么好方法可以做到这一点吗?

1 个答案:

答案 0 :(得分:0)

斯科特,

我认为对ASP.NET Web Forms框架的工作方式存在误解。所以首先只是一点理论。

ASP.NET Web窗体页面包含设计和代码隐藏文件。设计文件具有HTML标记和“控件”,它们是用户或自定义控件的引用标记。每个具有属性runat = "server"的元素都是服务器控件(意味着它可以通过其ID从后面的代码访问)。

在浏览器中打开页面时,ASP.NET会获取设计文件并处理这些控件引用,最后生成纯HTML。

ViewState是HTML中的一个隐藏变量,它保留了标有runat = "server"的所有控件的内部状态,并且还将属性EnableViewState设置为True。

假设你有EnableViewState = False的DataGrid。此网格包含包含服务器控件的行,您希望它们位于ViewState中。您仍然可以让他们拥有EnableViewState = True并且处于ViewState状态,您仍然可以绑定到这些子控件的事件。

所以即使DataGrid不在ViewState中,它的子节点也可以在ViewState中,你可以处理适当的事件。

如果您希望每次回发后显示数据,则需要在PageLoad事件中初始化DataGrid。

ViewState保持内部控制状态,因此您不能在ViewState中拥有某些控件属性,也不能在ViewState中拥有其他属性。但是,即使父控件不在ViewState中,您也可以将子控件(它们不是属性,它们是子实体!)放在ViewState中。

如果您希望我对此更加具体,请告诉我。如果你想深入了解Nikhil Kothari关于开发控件的精彩书籍。我想我把它看作电子书。