[ 月別 | 分類別 ]

[ASP.NET] 動的にコントロールを追加して、その値を取得する方法

2011-07-01 23:58:48

パソコン・インターネット

またASP.NETで試行錯誤したので載っけておく。(わかってる人には当たり前なんだろうけど、なぜかネットでずばりの回答を見つかれなかったんで。)

(7月8日追記:どうも、Page_PreInitで追加するほうがいいみたいとか? よくわからんが。)

まず、動的にコントロールを追加するだけなら、

Dim tx = New TextBox
tx.ID = "Text1"
txt.Text = "ABC"
Form1.Controls.Add(tx)

とかでOKってのはすぐわかった。でもこれだとボタンクリックなどしたあとにテキストボックスの値が取れない。

で、いろいろネットを漁ったあげく、なんとなくできた。

テキストボックスを1つ動的に作って、その値をコピーするテスト。

まずはページ。

<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Default3.aspx.vb" Inherits="Default3" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>動的にコントロールを追加して、ボタンを押したらその値を取り出すテスト</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
     <h1>動的にコントロールを追加して、ボタンを押したらその値を取り出すテスト</h1>
  <asp:Panel ID="Panel1" runat="server">
  </asp:Panel>
  <asp:Button ID="btnGO" runat="server" Text="GO" />
  <br />
  <asp:TextBox ID="txtResult" runat="server"></asp:TextBox>
    </div>
    </form>
</body>
</html>

次にコード。

Imports System.Web.UI.WebControls

Partial Class Default1
    Inherits System.Web.UI.Page

	Dim tx As TextBox

	Protected Sub Page_PreInit(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreInit
		tx = New TextBox
		tx.ID = "txtDynamic"
		Panel1.Controls.Add(tx)
	End Sub

	Protected Sub btnGO_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnGO.Click
		txtResult.Text = tx.Text
	End Sub
End Class

これで、うまく動く。動的に生成するテキストボックスをメンバーとして確保しておいて、Page_PreInitで生成するのがミソみたい。

ついでに、もちょっと凝ったものも載っけておく。ドロップダウンリストやら、テーブルへの配置やら、動的配列の使用(ReDimとか使うのはVB6的?)やら、いろいろやってるんでややこしいけど、こんな感じ。

まずはページ。

<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Default3.aspx.vb" Inherits="Default3" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
  <h1>
   動的にコントロールを動的配列で追加して、ボタンを押したらその値を取り出すテスト
  </h1>
  <div style="margin:10px">
    <asp:Button ID="Button1" runat="server" Text="Button" />
  </div>
  <div style="margin:10px">
    <asp:Table ID="Table1" runat="server">
    </asp:Table>
  </div>
  <div style="margin:10px">
    <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
    <asp:TextBox ID="TextBox2" runat="server"></asp:TextBox>
  </div>
</form>
</body>
</html>

テーブルを作っておいて、そこに動的にテキストボックスとドロップダウンリストを追加することにする。

次にコード。

Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.WebControls

Partial Class Default3
    Inherits System.Web.UI.Page


	'ここいらで動的に追加するコントロールを宣言しておく(今回は配列で)
	Dim tx() As System.Web.UI.WebControls.TextBox
	Dim ddl() As System.Web.UI.WebControls.DropDownList
	Dim cnt As Integer = 0
	Dim dt As System.Data.DataTable

	Protected Sub Page_PreInit(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init
		cnt = 3  '3セット追加することにする
		ReDim tx(cnt)
		ReDim ddl(cnt)
		Call CreateDT()  'ドロップダウンのソースはデータテーブルで作っておく
		For i = 0 To cnt - 1
			Dim tr As New TableRow
			Dim tc1 As New TableCell
			Dim tc2 As New TableCell

			tx(i) = New TextBox
			tx(i).ID = "Text" & i.ToString
			tc1.Controls.Add(tx(i))

			Call SetDdl(i)
			tc2.Controls.Add(ddl(i))

			tr.Cells.Add(tc1)
			tr.Cells.Add(tc2)
			Table1.Rows.Add(tr)
		Next
	End Sub

	Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
	End Sub

	Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
		Dim t1 As String = "" '結果がうまく取れるか試してみる
		Dim t2 As String = ""
		For i = 0 To cnt - 1
			If tx(i) IsNot Nothing Then
				Dim s As String = tx(i).Text
				t1 = t1 & s
			End If
			If ddl(i) IsNot Nothing Then
				Dim s As String = ddl(i).SelectedValue
				t2 = t2 & s
			End If
		Next
		TextBox1.Text = t1
		TextBox2.Text = t2
	End Sub

	Private Sub CreateDT()
		dt = New System.Data.DataTable
		dt.Columns.Add("ID", GetType(String))
		dt.Columns.Add("NAME", GetType(String))

		Dim row As System.Data.DataRow
		row = dt.NewRow()
		row("ID") = "aa"
		row("NAME") = "AAA"
		dt.Rows.Add(row)

		row = dt.NewRow()
		row("ID") = "bb"
		row("NAME") = "BBB"
		dt.Rows.Add(row)

		row = dt.NewRow()
		row("ID") = "cc"
		row("NAME") = "CCC"
		dt.Rows.Add(row)

		dt.AcceptChanges()
	End Sub

	Private Sub SetDdl(ByVal i As Integer)
		ddl(i) = New DropDownList
		ddl(i).ID = "ddl" & i.ToString
		ddl(i).DataSource = dt
		ddl(i).DataTextField = "NAME"
		ddl(i).DataValueField = "ID"
		ddl(i).DataBind()
	End Sub
End Class

これで動いたんで、めでたしめでたしということに。