14

私は次の本当に単純なコードを持っています

<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>

<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
    <asp:PlaceHolder ID="PlaceHolder1" runat="server">
    </asp:PlaceHolder>
    <asp:Button ID="Button1" runat="server" Text="Button" onclick="Button1_Click" />
</ContentTemplate>
</asp:UpdatePanel>

そしてコードビハインド

protected void Button1_Click(object sender, EventArgs e)
{
    Literal literal = new Literal();
    literal.Text = DateTime.Now.ToString();
    literal.ID = DateTime.Now.Ticks.ToString();

    // These both work fine the first time the button is clicked
    // but the second time nothing is added.
    UpdatePanel1.ContentTemplateContainer.Controls.Add(literal);
    PlaceHolder1.Controls.Add(literal);
}

私の問題は、リテラル コントロールが一度しか追加されないことにあります。私はグーグルとブログサイト(および本)を精査しましたが、運がありません. 私は何が欠けていますか?

4

2 に答える 2

25

asp.net では、ASPX ファイル内のコントロールはポストバックごとに自動的に生成されます。作成したコントロールは ASPX コードに含まれていないため、フレームワークはそれらを作成しません。Button1_Click メソッドを初めて実行するときに、ページにコントロールを 1 つ追加します。Button1_Click メソッドを 2 回目に実行すると、別のポスト バックが表示され、最初の余分なボタンは忘れられています。したがって、そのポストバックの結果、1 つ余分なボタンが再び取得されます。

これにより、ボタンをクリックするたびに追加のコントロールが 1 つ作成されます (ただし、コントロールが再作成されるため、ボタンを押すたびにタイムスタンプが更新されます)。

protected void Button1_Click(object sender, EventArgs e)
{
    int count = 0;

    if (ViewState["ButtonCount"] != null)
    {
        count = (int)ViewState["ButtonCount"];
    }

    count++;
    ViewState["ButtonCount"] = count;

    for (int i = 0; i < count; i++)
    {
        Literal literal = new Literal();
        literal.Text = DateTime.Now.ToString();
        literal.ID = DateTime.Now.Ticks.ToString();

        UpdatePanel1.ContentTemplateContainer.Controls.Add(literal);
        PlaceHolder1.Controls.Add(literal);
    }            
}
于 2009-02-16T12:22:23.003 に答える
3

上記の回答に同意しますが、このアプローチでは動的コントロールの状態は保存されません (正確には、状態は保存されますが、読み込まれません)。ビュー ステートの読み込みは、ページ ライフ サイクルの Load イベント セクションで呼び出され、ビュー ステートに保存されているコントロール値を割り当てます。ただし、この時点までにコントロールが作成されていない場合、以前のデータをロードすることはできないため、状態を維持するには、ロード イベント時またはその前に新しいコントロールを再作成する必要があります。

protected void Page_Load(object sender, EventArgs e)
{
    //PS: Below approach saves state as id is constant, it simply generates a new control with same id hence viewstate loads the value
    if (IsPostBack)
    {
        int count = 0;

        if (ViewState["ButtonCount"] != null)
        {
            count = (int)ViewState["ButtonCount"];
        }

        count++;
        ViewState["ButtonCount"] = count;

        for (int i = 0; i < count; i++)
        {
            TextBox literal = new TextBox();
            //literal.Text = DateTime.Now.ToString();
            literal.ID = "Textbox" + i.ToString();

            //UpdatePanel1.ContentTemplateContainer.Controls.Add(literal);
            PlaceHolder1.Controls.Add(literal);

        }
    }
}

コントロールを動的に追加する View State とポストバック

于 2014-08-22T20:32:36.410 に答える