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に保存されるのではないかと考え、コードを以下のように書き換えた場合の動作を見てみます。
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