2007年05月02日

動的コントロールのサンプル(ASP.NET 2.0)

GridViewは大変便利であるが、表形式の入力画面が欲しいときにはやや力不足なところがある。基本的に行単位でしか編集ができないし、任意のセルに自由に移動し入力することができない。

そこでセル毎に一つ一つコントロールを配置していく方法が求められるのだが、固定した行数とは限らないのでどうしても動的に作成したい。しかし動的コントロールの作成は結構面倒で分からない点多い。いろいろ試行錯誤してようやく何とかものになったノウハウをここで紹介したい。実際の業務で使っている仕組みなので参考になると思う。

表(コンテナ)は「Table Web コントロール」を使っている。
これはそもそも動的コントロール用に用意されたと言っても良い代物で、固定の表に使うにはどう考えても無駄でしかない。

サンプルはダウンロードして使えます。→ DynamicTableCreate.lzh
DynamicTableCreate2.lzh (2007.05.18更新)
「ETextBox+Buttonを作成」を追加しました。


動作画面は下図を。

@起動直後の画面:まだコントロールは一つも無い
起動直後

Aテキストを表に出力
テキストを出力

BHyperLinkコントロールを作成
リンクを作成

CTextBoxコントロールを作成
テキストボックスを作成

DButtonコントロールを作成、下はボタンをクリックしたもの
Buttonを作成

クリックイベントを起こしたところ

ETextBox+Buttonコントロールを作成
TextBoxの内容を取得
TextBox+Button

posted by なっちゃん at 19:32| 静岡 ☀| Comment(16) | TrackBack(1) | ASP.NET Tips | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
色々参考にさせてもらっています。

asp:Tableにて動的にコントロールを作成する事は出来たのですが、設定された値を取得する方法がわかりません。
例えば、
CTextBoxコントロールを作成
では、TextBoxの値を取得したりすると思うのですが、やり方がわかるようでしたら教えていただけませんか。
表の下にasp:Buttonを配置し、押されたイベントで値を取得したいのです。
Posted by だー at 2007年05月17日 18:12
動的に作成したコントロールのプロパティを取得するには、FindControlを使います。
以前に配列コントロールのTipsでも紹介してます。
http://natchan-develop.seesaa.net/article/13906919.html

今回のサンプルにも追加しておきました。
ETextBox+Buttomコントロールを作成

Posted by なっちゃん at 2007年05月18日 01:08
おお、サンプル追加ありがとうございます!
しかし実は、FindControlは既に試してまして、コントロールを取得できませんでした。
なっちゃんさんのサンプルで新しくWebサイトを作ってみたら正常動作しました。
しかし、なっちゃんさんのサンプルの正常動作した部分を抜き出して、私のうまくいかなかったWebアプリケーションで試してみると、やはりコントロールが取得できません。
違いとして思いつくのは、私の方はMasterPageを使用しているページって事です。(VB.NETでなくC#ってのもありますね。)
PostBackが発生すると、MasterPageのPage_LoadとContentの方のPage_Loadの両方が実行されるので、そのあたりが原因なのかもしれません。
単純なMasterPageを使ったページを作成してみて、なっちゃんさんのサンプルを貼り付けて試してみたいと思います。
Posted by だー at 2007年05月18日 17:03
マスターページを使った場合のFindControlは注意が必要です。
実はマスターページを使用したときのFindControlをTipsに取り上げる予定でしたが、Microsoftのヘルプにもあるのでわざわざ補足することもないと思って止めたのです。
プログラムによるASP.NETマスターページの操作
http://msdn2.microsoft.com/ja-jp/library/c8y19k6h(vs.80).aspx

要はマスターページ上であろうとなかろうと、コンテナ上にあるコントロールの探し方は(コンテナ).FindControl()となることを覚えておけば良いのです。GridViewの列にテンプレートとして配置されたコントロールなら(GridViewRow).FindControl()。
コンテナ名を付けないと標準のコンテナ上を暗黙で探すので見つからないのです。
Posted by なっちゃん at 2007年05月18日 17:29
なるほど、コンテナ名指定をしないから探せないのですね。
this.Table1.Rows[i].FindControl("コントロールID");
とする事で、取得する事が出来ました。
ありがとうございます!
Posted by だー at 2007年05月21日 15:24
初めまして。
動的コントロールの作成、
で検索してたどり着きました。

ASP.NETを使用しての開発が初めてだったので、
他のエントリもとてもわかりやすく、
ものすごく役に立ちました。

本当に感謝しております。
どうもありがとうございました。
Posted by チョビ at 2008年09月16日 12:59
何事も最初は判らないことばかりです。
しかも年を取るとすぐ忘れてしまいます。
このTipsは自分の覚書の意味もあるので
自分でもよく利用しています(^o^;
Posted by なっちゃん at 2008年09月16日 13:14
突然失礼します。
findcontrolについて調べていたらこちらにたどり着きました。。今までも違うエントリを参考にして、大変助かっています。。ありがとうございます。

しかし、現在このエントリーと同じ症状で作業が止まってしまっています。。
状況としましては、
MasterPageを使用し、その中でasp:tableでtableを作成し、(tableのidはtable1)TableHeaderRowで作成したTableHeaderCellに文字を変動的に表示したいのです。こちらを参考に
CType(Master.FindControl("ContentPlaceHolder1").FindControl("table1").FindControl("clName" & i.ToString), TableHeaderCell).Text = dtTable.Rows(i)(0).ToString
等を試したのですが、うまくいきません。。。。。

やりたいこととしては、forでまわしつつ連番のIDを振ったTableHeaderCellに文字を表示したいのですが。。。。。
エラー内容は
「型 'System.Web.UI.WebControls.TextBox' のオブジェクトを型 'System.Web.UI.WebControls.TableHeaderCell' にキャストできません。」
と出ます。。idを動的にせず(i等を使わず)直接指定した場合はclName1.text = "文字列"で表示できるのでCTypeを使用しているのですが・・・・・

自分に技術があまり無い為何を重点に質問したいのかも分からず、そのため文章も荒れていると思いますが、お時間がありましたら何か助言を頂けると幸いです。。。
お願いします。。。。
Posted by おさむ at 2008年09月20日 22:32
実際にサンプルを作る余裕はないので、見当だけでお話しするのですが、
FindControlの結果を一つ一つオブジェクト変数に代入して、確実に見つかったものに対して次のオブジェクトをFindControlする方がよいと思います。
またその方がエラーする場所が特定できてデバッグしやすいと思うのです。

Posted by なっちゃん at 2008年09月22日 22:14
まさにこんなサイトを待っていましたという感じです。
なっちゃん様、ありがたく見させて頂きます
Posted by よっちゃん at 2010年03月25日 14:30
こんにちは
動的にTableを作成し、コントロールを配置したかったのでこのページが大変参考になりました。
サンプル通りにコーディングしたら、やりたいことができました。ありがとうございました。

質問なのですが、
動的に配置したテキスト等の内容を、ポストバック時に取得したいのですが、ポストバックと同時にコントロールが消えてしまい、取得できません。
どうしたらいいかご存知でしたら教えていただきたいです。
お返事お待ちしています。
Posted by まろん at 2010年07月28日 10:20
「TextBox+Button配置」のサンプルを実行してもらえば分かると思うのですが。
ボタンを押せば動的テキストボックスの入力内容を(初期値だけでなく、変更した内容でも)ちゃんと取得してメッセージを表示してますよ。
動的なコントロールの作成ルーチンとAddHandlerで追加したClickイベントの内容をよく調べてください。
また、大事なのはFormロード時にもちゃんと動的コントロールを再作成しているということです。これをしないとポストバック時にはコントロールが無いことになります。
Posted by なっちゃん at 2010年07月28日 10:55
なっちゃんさんへ
よく読まずに書き込みしてしまい、申し訳ありませんでした。すばやい返信にとても感謝しています。
再表示すれば簡単に取得できました、ありがとうございました。
Posted by まろん at 2010年07月28日 11:15
こんにちは。
動的のTable作成とコントロールの配置をしたかったので、大変参考になります。

ただ、まろんさんの書き込みにもありますが
動的に配置した内容を、ポストバック時に取得したいのですが、ポストバックと同時にコントロールが消えてしまい、取得できません。

例えば、「Button配置」のサンプルで
 1.3×5のTable作成
 2.行数を2に変更 (←どこもクリックはしない)
 3.Tableの(3,5)位置のボタンをクリック
とするとポストバック時に行数が変わってしまったため、前の状態では取得できません。

やりたいことは、画面の条件(サンプルでは行数と列数)を変えた場合でも、画面に描画された時のイベントを発生させたいのですが、何か分かればご教授願います。
Posted by しろうと at 2010年10月09日 10:09
しろうとさんの質問というか要望はサンプルの趣旨とは違いますね。行数や桁数を変える指示をしているのに、その条件が適用される前の情報を取得したいと言っているわけです。

それを行うにはあらかじめ元の情報を別のHiddenコントロールなどに保持しておき、ポストバック時には元データで再作成しておき、イベント発生後に新しい行・桁数でテーブルを再作成するなどするしかないでしょう。
Posted by なっちゃん at 2010年10月09日 12:39
早速の回答ありがとうございます。

>あらかじめ元の情報を別のHiddenコントロールなどに保持しておき

そうですよね。
退避しないで、何かできるかと思っていたので甘かったです。。

自分がやりたいことが、別の方法でもできるかどうか検討したいと思います。
ありがとうございました。
Posted by しろうと at 2010年10月09日 13:01
コメントを書く
お名前: [必須入力]

メールアドレス:

ホームページアドレス:

コメント: [必須入力]

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。

この記事へのトラックバック

動的コントロールのサンプル(ASP.NET 2.0)へのリンクです。
Excerpt: 動的コントロールのサンプル(ASP.NET 2.0)へのリンクです。
Weblog: DS7のちょっとずつ
Tracked: 2012-02-16 11:57
×

この広告は90日以上新しい記事の投稿がないブログに表示されております。