如何根据用户输入添加持久动态控件(而不是初始页面加载)

时间:2010-10-13 11:23:35

标签: asp.net page-lifecycle dynamic-controls

我熟悉在第一次加载页面和后续回发时创建和保持动态控件,但我在使用以下 用户启动的 方案时遇到问题。

在我的演示中,我有一个占位符,两个按钮和一个文字

<div>
    <asp:PlaceHolder ID="phResponses" runat="server" />
</div>
<div>
    <asp:Button ID="btnAdd" Text="Add" runat="server" OnClick="Add"/>
    <asp:Button ID="btnInspect" Text="Inspect" runat="server" OnClick="Inspect"/>
</div>
<div>
    <asp:Literal ID="litResult" runat="server"/>
</div>

我希望用户能够点击添加按钮以提供回复,所以我有...

protected void Page_Init(object sender, EventArgs e)
{
    BuildControls();
}

protected void Add(object sender, EventArgs e)
{
    BuildControls();
}

protected void BuildControls()
{
    phResponses.Controls.Add(new LiteralControl { ID = "response_" + _Count.ToString() });
    _Count++;
}

_Count是一个静态成员变量,使我能够为新控件提供唯一ID。我意识到我需要在Page_Init上重建动态控件,但问题是我最终在每次回发时都有2个新的Literal控件。此外,如果将任何Text属性放入新控件中,则在重建控件时它将丢失。

那么如何避免添加多个控件以及如何在重建这些控件时保留新添加的属性?

我使用以下内容检查回复

protected void Inspect(object sender, EventArgs e)
{
    foreach (var control in phResponses.Controls)
    {
        if (control is LiteralControl)
        {
            litResults.Text += "<p>" + control.Text + " : " + control.ID + "</p>";
        }
    }
}

由于在Page_Init

上重建,它本身会增加另一个不需要的控件

1 个答案:

答案 0 :(得分:0)

我不确定我是否完全明白你在问什么,但看起来你只想确保BuildControls每个生命周期只调用一次。您可以通过进行以下更改来实现此目的:

  1. 添加新的private bool _isControlsBuilt = false;
  2. 在致电Page_Init之前,先更改_isControlsBuilt以检查BuildControls
  3. _isControlsBuilt设置为true内的BuildControls
  4. 确保BuildControls中的Page_Init早于BuildControls
  5. 至于在回发时丢失控件的值,那就是他们永远不会访问viewstate。我不确定它是否有用,但我的第一个猜测是在protected void BuildControls() { LiteralControl newLiteral = new LiteralControl { ID = "response_" + _Count }; this.RegisterRequiresControlState(newLiteral); phResponses.Controls.Add(newLiteral); _Count++; _isControlsBuilt = true; } 末尾添加一行以致电page lifecycle

    {{1}}

    如果这不起作用(这可能意味着它是_view_state,而不是对此重要的_control_state),您可能需要查看滚动自己的视图状态。我在Page.RegisterRequiresControlState中写了关于如何做到这一点,你可能会发现它很有用。