C# 动态创建的控件和ASP.NET页面生命周期

C# 动态创建的控件和ASP.NET页面生命周期,c#,asp.net,events,updatepanel,page-lifecycle,C#,Asp.net,Events,Updatepanel,Page Lifecycle,我正在从事一个ASP.NET项目,其中绝大多数表单都是在运行时动态生成的(表单定义存储在数据库中以供自定义)。因此,每当OnLoad触发时,我必须动态创建控件并将其添加到页面,而不管IsPostBack如何。这一直运行得很好,.NET负责管理这些控件的ViewState protected override void OnLoad(EventArgs e) { base.OnLoad(e); RenderDynamicControls() } private void Rend

我正在从事一个ASP.NET项目,其中绝大多数表单都是在运行时动态生成的(表单定义存储在数据库中以供自定义)。因此,每当OnLoad触发时,我必须动态创建控件并将其添加到页面,而不管IsPostBack如何。这一直运行得很好,.NET负责管理这些控件的ViewState

protected override void OnLoad(EventArgs e)
{
    base.OnLoad(e);
    RenderDynamicControls()
}

private void RenderDynamicControls()
{
    //1. call service layer to retrieve form definition
    //2. create and add controls to page container
}
我有一个新的要求,如果用户点击一个给定的按钮(这个按钮是在设计时创建的),页面应该以稍微不同的方式重新呈现。因此,除了在OnLoad中执行的代码(即RenderDynamicControls()),我还有以下代码:

protected void MyButton_Click(object sender, EventArgs e)
{
    RenderDynamicControlsALittleDifferently() 
}

private void RenderDynamicControlsALittleDifferently()
{
    //1. clear all controls from the page container added in RenderDynamicControls()

    //2. call service layer to retrieve form definition

    //3. create and add controls to page container
}
我的问题是,这真的是实现我追求的目标的唯一途径吗?仅仅为了响应一个按钮的点击,就可以有效地将表单渲染两次,这似乎超出了黑客的范围。我从研究中得出结论,这就是ASP.NET中页面生命周期的工作原理:即,在调用子事件之前,必须在每次回发时启动OnLoad。尽管如此,在不得不喝kool-aid之前,还是值得与SO社区核实一下

另一方面,一旦我完成了这个特性,我计划在页面上抛出一个UpdatePanel,通过Ajax执行页面更新。任何能使这种转换更容易的代码/建议都将不胜感激。

从德克到德克:-)

使用RenderDynamic控件是什么意思?创建和设置控件?如果这是您的意图,则ASP.NET不是在管理您的ViewState,而是在管理您的ViewState。如果每次加载时都填充控件,则始终会覆盖现有的ViewState

如果要使用ViewState,请在pages init事件中创建控件并在load事件中填充它们,但前提是请求不是回发。这是必要的,因为ASP.NET会在init和load之间重新创建ViewState。这也是您描述的两个“渲染周期”的原因。您需要第一个控件创建周期,因为如果没有适当的控件集,ASP.NET无法还原ViewState,并且如果没有它,ASP.NET无法对您的响应做出正确的反应

回到你的代码:一般来说,你的RenderDynamicControlsAlletter是不起作用的——因为你在页面生命周期中创建控件太晚了,你会在控件集合中插入新对象,从而破坏ViewState。在类似的情况下,我通过将页面重定向到自身(Response.Redirect)解决了这个问题。在这种情况下,RenderDynamicControls将根据您更改内部状态后的“稍微不同的情况”执行此任务。

从Dirk到Dirk:-)

使用RenderDynamic控件是什么意思?创建和设置控件?如果这是您的意图,则ASP.NET不是在管理您的ViewState,而是在管理您的ViewState。如果每次加载时都填充控件,则始终会覆盖现有的ViewState

如果要使用ViewState,请在pages init事件中创建控件并在load事件中填充它们,但前提是请求不是回发。这是必要的,因为ASP.NET会在init和load之间重新创建ViewState。这也是您描述的两个“渲染周期”的原因。您需要第一个控件创建周期,因为如果没有适当的控件集,ASP.NET无法还原ViewState,并且如果没有它,ASP.NET无法对您的响应做出正确的反应


回到你的代码:一般来说,你的RenderDynamicControlsAlletter是不起作用的——因为你在页面生命周期中创建控件太晚了,你会在控件集合中插入新对象,从而破坏ViewState。在类似的情况下,我通过将页面重定向到自身(Response.Redirect)解决了这个问题。在这种情况下,RenderDynamicControls将根据您更改内部状态后的“稍微不同的情况”完成此工作。

欢迎使用ASP.NET。准备将所有逻辑抛出窗口欢迎使用ASP.NET。准备将所有逻辑抛出窗口