为啥 ASP.NET 动态控件即使添加到 Page_Load 中也能保持 ViewState?

Posted

技术标签:

【中文标题】为啥 ASP.NET 动态控件即使添加到 Page_Load 中也能保持 ViewState?【英文标题】:Why can ASP.NET Dynamic controls keep the ViewState even when added in Page_Load?为什么 ASP.NET 动态控件即使添加到 Page_Load 中也能保持 ViewState? 【发布时间】:2012-03-21 20:23:46 【问题描述】:

我做了一些与动态控件和 ViewState 相关的研究。

我读到,为了保持动态控件的 ViewState,您必须将其添加到 Page_Init 事件中。这是有道理的,因为 PageLifeCycle 是:

    初始化。 加载视图状态。 加载回传数据。 加载。 引发PostbackEvent。 保存视图状态。 渲染。

但是我制作了一个测试应用程序,我发现即使我在 Page_Load 事件中而不是之后添加控件,ViewState 和属性值也会保留。从这里开始,我只发现了矛盾的信息。有人说控件可能会赶上 PageLifeCycle 其他人说您必须将它们添加到 Page_Init 中。有人可以帮我澄清一下吗?

我也在msdn中找到:

注意您也许可以在 Page_Load 事件处理程序并正确维护视图状态。它 一切都取决于您是否设置了 以编程方式动态加载控件,如果是这样,当你 相对于 Controls.Add(dynamicControl) 行。彻底的 对此的讨论有点超出本文的范围,但 它可能起作用的原因是因为 Controls 属性的 Add() 方法 递归地将父视图状态加载到其子视图中,甚至 尽管加载视图状态阶段已经过去。

但我并没有完全理解这一点,所以我希望有人能解释一下。提前谢谢你。

【问题讨论】:

【参考方案1】:

此代码将实际演示它:

protected void Page_Load(object sender, EventArgs e)

    Button b1 = new Button();
    Button b2 = new Button();
    if (!IsPostBack)
    
        b1.Text = "Button1";
    
    this.form1.Controls.Add(b1);
    this.form1.Controls.Add(b2);
    if (!IsPostBack)
    
        b2.Text = "Button2";
    

因此,如果您在将控件添加到表单后对其进行修改,它将保持其视图状态,但如果您在将其添加到表单之前对其进行修改,则文本不会使其进入视图状态。这是发生了什么 - 正是为什么这是另一个问题(实际上与我阅读文档时的想法相反)。

编辑 我忘了提 - 本质上这是因为当通过 Controls.Add() 将页面添加到控件树时,控件在页面生命周期中播放以“赶上”页面 - 关于这方面的文章数不胜数,因为没有什么是直截了当的。

【讨论】:

【参考方案2】:

在过去(ASP.NET 2.0 或 3.5,不确定),当尝试实现与您提到的相同时,我必须在 Page_Init 中添加控件。在 Page_Load 中添加它们我不会看到客户端所做的更改到达服务器端,这是非常有意义的,因为当框架试图将视图状态绑定到控件时,它们还没有创建。

知道这种情况发生了变化,我感到非常惊讶。也许在 ASP.NET 4.0 中引入了一些东西?

【讨论】:

【参考方案3】:

在 NET 4.5 中,只需重写 CreateChildControls() 方法并将其放置在动态控件构建中。

【讨论】:

以上是关于为啥 ASP.NET 动态控件即使添加到 Page_Load 中也能保持 ViewState?的主要内容,如果未能解决你的问题,请参考以下文章

从 ASP.NET 服务器控件动态添加 CSS 文件

在 Asp.net C# 中创建动态控件,并缓存控件并绑定数据

在引导模式主体中动态添加的 asp.net 按钮/链接按钮 web 控件不会回发

ASP.NET用户自定义控件

ASP.NET动态创建控件

asp.net 动态添加多个用户控件