0

ページの最初の読み込み時とその後のポストバック時に動的コントロールを作成して永続化することには慣れていますが、ユーザーが開始した次のシナリオで問題が発生しています...

私のデモでは、プレースホルダー、2 つのボタン、およびリテラルがあります。

<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 つの新しいリテラル コントロールになってしまうことです。また、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 での再構築のために、それ自体が別の不要なコントロールを追加します

4

1 に答える 1

0

あなたが求めていることをよく理解しているかどうかはわかりませんが、BuildControlsライフサイクルごとに 1 回だけ呼び出されるようにしたいだけのようです。次の変更を加えることで、これを行うことができます。

  1. 新しい を追加しprivate bool _isControlsBuilt = false;ます。
  2. を呼び出す前Page_Initに確認するように変更します。_isControlsBuiltBuildControls
  3. 内に設定_isControlsBuilttrueますBuildControls
  4. よりもページのライフサイクルBuildControlsの早い段階で発生することを確認してください。Page_Init

ポストバックでコントロールの値が失われることについては、viewstate にヒットすることはありません。それが機能するかどうかはわかりませんが、最初に推測するのは、BuildControlsto callの最後に次の行を追加することPage.RegisterRequiresControlStateです。

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

    _Count++;
    _isControlsBuilt = true;
}

それがうまくいかない場合 (これは、ここで重要なのは _control_state ではなく、_view_state であることを意味している可能性があります)、独自のビューステートのローリングを検討する必要がある場合があります。#3854193 への回答でその方法について書きました。これは役に立つかもしれません。

于 2010-10-13T12:55:01.960 に答える