ASP.NETページで動的にコントロールを生成する - 単純な動的コントロールの生成 - ASP.NET

ASP.NETのWebフォームに動的にコントロールを生成するコードを紹介します。

プログラム例

UI

ASP.NETアプリケーションを作成し、Webフォームを配置します。以下のページを作成します。PlaceHolderを1つ、Labelを1つ、Buttonを1つ配置します。


UIのXMLは以下になります。
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="SimpleControlGenerate.aspx.cs" Inherits="GenerateControl.SimpleControlGenerate" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <title></title>
</head>
<body>
  <form id="form1" runat="server">
    <div>
      <asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder>
    </div>
    <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label><br />
    <asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
  </form>
</body>
</html>

コード

以下のコードを記述します。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace GenerateControl
{
  public partial class SimpleControlGenerate : System.Web.UI.Page
  {
    private CheckBox cb1;
    private CheckBox cb2;
    private CheckBox cb3;

    protected void Page_Load(object sender, EventArgs e)
    {
    }

    protected void Page_PreInit(object sender, EventArgs e)
    {
      cb1 = new CheckBox();
      cb1.Text = "CheckBox1";
      PlaceHolder1.Controls.Add(cb1);

      cb2 = new CheckBox();
      cb2.Text = "CheckBox2";
      PlaceHolder1.Controls.Add(cb2);

      cb3 = new CheckBox();
      cb3.Text = "CheckBox3";
      PlaceHolder1.Controls.Add(cb3)
    }

    protected void Button1_Click(object sender, EventArgs e)
    {
      try {
        if (cb1.Checked == true) {
          Label1.Text = "CheckBox1 がチェックされています";
        }
      }
      catch (Exception exc) {
      }
      finally {
      }
    }
  }
}

解説

Page_PreInit

PreInitイベントはページを初期化する際に呼び出されます。

  cb1 = new CheckBox();
  cb1.Text = "CheckBox1";
  PlaceHolder1.Controls.Add(cb1);

  cb2 = new CheckBox();
  cb2.Text = "CheckBox2";
  PlaceHolder1.Controls.Add(cb2);

  cb3 = new CheckBox();
  cb3.Text = "CheckBox3";
  PlaceHolder1.Controls.Add(cb3);
上記コードにより、ページ初期化時にチェックボックス3つを作成しPlaceHolder1に配置します。

button1_click

  if (cb1.Checked == true) {
    Label1.Text = "CheckBox1 がチェックされています";
  }
Button1がクリックされた際に、CheckBox1にチェックがついていれば、Label1にCheckBox1がチェックされている旨のメッセージを表示します。

実行結果

プロジェクトを実行します。下図の画面が表示されます。


CheckBox2とCheckBox3にチェックをします。


Buttonをクリックします。ページが再読み込みされますがCheckBox2, CheckBox3のチェックボックスのチェックはついたままです。チェックボックスのチェック情報がポストされる(またはViewStateに保存される)ため、ページが切り替わってもチェック状態が保持されることがわかります。


続いてCheckBox1をチェックし、Buttonをクリックします。


ページが切り替わります。LabelにCheckBox1がチェックされた旨のメッセージが表示されます。また、CheckBox1にチェックが付いたままになっています。

補足:ポストバック時にコントロールを生成しない動作にした場合

生成されたコントロールがViewStateに保存されるのではないかと考え、コードを以下のように書き換えた場合の動作を見てみます。
default.aspx.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace GenerateControl
{
  public partial class SimpleControlGenerate : System.Web.UI.Page
  {
    private CheckBox cb1;
    private CheckBox cb2;
    private CheckBox cb3;

    protected void Page_Load(object sender, EventArgs e)
    {
    }

    protected void Page_PreInit(object sender, EventArgs e)
    {
      if (IsPostBack == false) {
        cb1 = new CheckBox();
        cb1.Text = "CheckBox1";
        PlaceHolder1.Controls.Add(cb1);

        cb2 = new CheckBox();
        cb2.Text = "CheckBox2";
        PlaceHolder1.Controls.Add(cb2);

        cb3 = new CheckBox();
        cb3.Text = "CheckBox3";
        PlaceHolder1.Controls.Add(cb3);
      }
    }

    protected void Button1_Click(object sender, EventArgs e)
    {
      try {
        if (cb1.Checked == true) {
          Label1.Text = "CheckBox1 がチェックされています";
        }
      }
      catch (Exception exc) {
      }
      finally {
      }
    }
  }
}

解説

if文を追記し、コントロールの生成をポストバックでない場合のみに制限します。
    protected void Page_PreInit(object sender, EventArgs e)
    {
      if (IsPostBack == false) {
        cb1 = new CheckBox();
        cb1.Text = "CheckBox1";
        PlaceHolder1.Controls.Add(cb1);

        cb2 = new CheckBox();
        cb2.Text = "CheckBox2";
        PlaceHolder1.Controls.Add(cb2);

        cb3 = new CheckBox();
        cb3.Text = "CheckBox3";
        PlaceHolder1.Controls.Add(cb3);
      }
    }

実行結果

プロジェクトを実行します。先ほどと同じ下図の画面が表示されます。


CheckBox1,CheckBox2にチェックをしButtonをクリックします。


Button1_Clickメソッドの内部にtry~exceptブロックを記述していない場合、NullReferenceExceptionエラーが発生します。ポストバック時にコントロールは再作成されていないためエラーが発生します。動的なコントロールの作成はページのロード時に常に実行する必要があります。


エラーをキャッチし処理を継続させた場合、画面には動的なコントロールは表示されない結果となります。


補足:ボタンのクリックなどのイベント発生時にコントロールを生成した場合

ボタンのクリックなどのイベント発生時にコントロールを生成した場合の動作を確認します。

UI

下図のUIを作成します。PlaceHolderとButtonを2つ設置します。


aspxファイルのコードは下記となります。
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ClickControlCenerate.aspx.cs" Inherits="GenerateControl.ClickControlCenerate" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <title></title>
</head>
<body>
  <form id="form1" runat="server">
    <div>
      <div>
        <asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder>
      </div>
      <asp:Button ID="Button1" runat="server" Text="Button1" OnClick="Button1_Click" />
      <asp:Button ID="Button2" runat="server" Text="Button2" />
    </div>
  </form>
</body>
</html>

コード

下記のコードを記述します。

実行結果

プロジェクトを実行します。Webブラウザが起動し数の画面が表示されます。


[Button1]をクリックすると、TextBoxが2つ、Buttonが1つ動的に生成されPlaceHolder内に表示されます。


上図のコントロールが表示されている状態で[Button2]をクリックするとページが切り替わりますが、生成されたコントロールは非表示になってしまいます。同様に生成されたコントロールのボタンをクリックしてもコントロールは非表示になります。


コントロールはViewStateやその他のストレージに状態保存されないため、ポストバック時にもコントロールの生成は必要であり、ページのイベントで作成する場合もポストバックの際にコントロールを画面に表示する必要がある場合は、ページ表示のタイミングで再度コントロールを生成する必要があります。
著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用
最終更新日: 2018-03-27
作成日: 2013-05-27
iPentec all rights reserverd.