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



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

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

  1. 初始化
  2. LoadViewState
  3. LoadPostbackData
  4. 加载
  5. RaisePostbackEvent
  6. 保存视图状态
  7. 渲染

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

同样在msdn中,我发现:

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

但我真的不完全理解,所以我希望有人能解释一下。提前谢谢。

此代码将在操作中演示它:

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()添加到控件树时,控件在页面生命周期中一直在"追赶"页面——关于这一点的文章层出不穷,因为没有太多直截了当的内容。

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

我很惊讶知道这一切都变了。也许是在ASP.NET 4.0中引入的东西?

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

最新更新