none
動的に生成したコントロールの値保持について RRS feed

  • 質問

  • いつもお世話になっております。

    動的に追加したコントロールの値の保持がうまくできずご質問させて頂きました。

    最終的にやりたいことはDBからの値によってx個のテキスト(inputタグ)を追加し、

    処理を行いたいのですが、まずは基本的な動作を確認するため下記①②の処理を作って試行錯誤しています。

    ①Page_Load時(非ポストバック時)に動的にコントロール追加し、テキストをセット。

    ②ボタンクリックでポストバックを発生させ、ポストバック時に再度コントロールを追加。

    この時、①でセットした文字列が②の時点で保持(引き継がれる)と思ったのですが、

    消えてしまうのはなぜでしょうか。

    <asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolderContent" runat="Server">    
      <asp:Panel ID="PanelTextList" runat="server"></asp:Panel>
       <asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
    </asp:Content>
    protected void Page_Load(object sender, EventArgs e)
    {
      if (!IsPostBack)
      {
          var txth = "aa";
          string inputTag = String.Format(@"<div class=""form-group form-inline"">
          <input type=""text"" runat=""server"" class=""form-control"" name=""text"" value=""{0}"" /><br />", txth);
          this.PanelTextList.Controls.Add(new LiteralControl(inputTag));
      }
      else
      {
          string inputTag = String.Format(@"<div class=""form-group form-inline"">
         <input type=""text"" runat=""server"" class=""form-control"" name=""text"" /><br />");
           this.PanelTextList.Controls.Add(new LiteralControl(inputTag));
      }
    
    }
    
    protected void Button1_Click(object sender, EventArgs e)
    {
        //PostBackを発生させる
    }
    

    -----------------------------------------------------------------

    開発環境
    Windows8 Pro、VsiaulStudio Commity2013 (ASP.net C#)
    ASP.NET開発サーバ、IIS8、Framework4.5
    MySQL Server 5.6、MySQL Connector Net 6.9.6
    -------------------------------------------------------------------

    2015年4月14日 12:12

回答

  • 本来ステートレスな Web アプリが、ASP.NET Web Forms アプリでは一見ステートフルに見えるのは、サーバーコントロールと ViewState のおかげと言うことは理解されているでしょうか?

    > この時、①でセットした文字列が②の時点で保持(引き継がれる)と思ったのですが、
    > 消えてしまうのはなぜでしょうか。

    input 要素がサーバーコントロールになってないので「①でセットした文字列」が ViewState に保持されないからでしょう。

    input 要素の文字列 inputTag に runat="server" 属性を追加してサーバーコントロールにしたつもりかもしれませんが、new LiteralControl(inputTag) とリテラルとして Panel に追加していますよね。なので、ASP.NET はそれをサーバーコントロールとして認識していません。

    new TextBox() または new HtmlInputText() として input 要素に相当するサーバーコントロールを Panel に追加してみてください。

    • 回答としてマーク hys73 2015年4月14日 20:47
    2015年4月14日 13:40

すべての返信

  • 本来ステートレスな Web アプリが、ASP.NET Web Forms アプリでは一見ステートフルに見えるのは、サーバーコントロールと ViewState のおかげと言うことは理解されているでしょうか?

    > この時、①でセットした文字列が②の時点で保持(引き継がれる)と思ったのですが、
    > 消えてしまうのはなぜでしょうか。

    input 要素がサーバーコントロールになってないので「①でセットした文字列」が ViewState に保持されないからでしょう。

    input 要素の文字列 inputTag に runat="server" 属性を追加してサーバーコントロールにしたつもりかもしれませんが、new LiteralControl(inputTag) とリテラルとして Panel に追加していますよね。なので、ASP.NET はそれをサーバーコントロールとして認識していません。

    new TextBox() または new HtmlInputText() として input 要素に相当するサーバーコントロールを Panel に追加してみてください。

    • 回答としてマーク hys73 2015年4月14日 20:47
    2015年4月14日 13:40
  • 勉強になります。

    runat="server" 属性を追加することで、サーバコントロールになっていると解釈しておりました。

    LiteralControl をMSDNで確認すると、きちんと記述してありました

    LiteralControl クラス

    HTML 要素、テキスト、およびサーバーでの処理を必要としない ASP.NET ページのその他の文字列を表します。

    new TextBox() として、追加することで、無事期待通りの動作を行うことができました。

    ありがとうございました。

    2015年4月14日 20:55