そこでセル毎に一つ一つコントロールを配置していく方法が求められるのだが、固定した行数とは限らないのでどうしても動的に作成したい。しかし動的コントロールの作成は結構面倒で分からない点多い。いろいろ試行錯誤してようやく何とかものになったノウハウをここで紹介したい。実際の業務で使っている仕組みなので参考になると思う。
表(コンテナ)は「Table Web コントロール」を使っている。
これはそもそも動的コントロール用に用意されたと言っても良い代物で、固定の表に使うにはどう考えても無駄でしかない。
サンプルはダウンロードして使えます。→
DynamicTableCreate2.lzh (2007.05.18更新)
「ETextBox+Buttonを作成」を追加しました。
動作画面は下図を。
@起動直後の画面:まだコントロールは一つも無い

Aテキストを表に出力

BHyperLinkコントロールを作成

CTextBoxコントロールを作成

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


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

asp:Tableにて動的にコントロールを作成する事は出来たのですが、設定された値を取得する方法がわかりません。
例えば、
CTextBoxコントロールを作成
では、TextBoxの値を取得したりすると思うのですが、やり方がわかるようでしたら教えていただけませんか。
表の下にasp:Buttonを配置し、押されたイベントで値を取得したいのです。
以前に配列コントロールのTipsでも紹介してます。
http://natchan-develop.seesaa.net/article/13906919.html
今回のサンプルにも追加しておきました。
ETextBox+Buttomコントロールを作成
しかし実は、FindControlは既に試してまして、コントロールを取得できませんでした。
なっちゃんさんのサンプルで新しくWebサイトを作ってみたら正常動作しました。
しかし、なっちゃんさんのサンプルの正常動作した部分を抜き出して、私のうまくいかなかったWebアプリケーションで試してみると、やはりコントロールが取得できません。
違いとして思いつくのは、私の方はMasterPageを使用しているページって事です。(VB.NETでなくC#ってのもありますね。)
PostBackが発生すると、MasterPageのPage_LoadとContentの方のPage_Loadの両方が実行されるので、そのあたりが原因なのかもしれません。
単純なMasterPageを使ったページを作成してみて、なっちゃんさんのサンプルを貼り付けて試してみたいと思います。
実はマスターページを使用したときのFindControlをTipsに取り上げる予定でしたが、Microsoftのヘルプにもあるのでわざわざ補足することもないと思って止めたのです。
プログラムによるASP.NETマスターページの操作
http://msdn2.microsoft.com/ja-jp/library/c8y19k6h(vs.80).aspx
要はマスターページ上であろうとなかろうと、コンテナ上にあるコントロールの探し方は(コンテナ).FindControl()となることを覚えておけば良いのです。GridViewの列にテンプレートとして配置されたコントロールなら(GridViewRow).FindControl()。
コンテナ名を付けないと標準のコンテナ上を暗黙で探すので見つからないのです。
this.Table1.Rows[i].FindControl("コントロールID");
とする事で、取得する事が出来ました。
ありがとうございます!
動的コントロールの作成、
で検索してたどり着きました。
ASP.NETを使用しての開発が初めてだったので、
他のエントリもとてもわかりやすく、
ものすごく役に立ちました。
本当に感謝しております。
どうもありがとうございました。
しかも年を取るとすぐ忘れてしまいます。
このTipsは自分の覚書の意味もあるので
自分でもよく利用しています(^o^;
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を使用しているのですが・・・・・
自分に技術があまり無い為何を重点に質問したいのかも分からず、そのため文章も荒れていると思いますが、お時間がありましたら何か助言を頂けると幸いです。。。
お願いします。。。。
FindControlの結果を一つ一つオブジェクト変数に代入して、確実に見つかったものに対して次のオブジェクトをFindControlする方がよいと思います。
またその方がエラーする場所が特定できてデバッグしやすいと思うのです。
なっちゃん様、ありがたく見させて頂きます
動的にTableを作成し、コントロールを配置したかったのでこのページが大変参考になりました。
サンプル通りにコーディングしたら、やりたいことができました。ありがとうございました。
質問なのですが、
動的に配置したテキスト等の内容を、ポストバック時に取得したいのですが、ポストバックと同時にコントロールが消えてしまい、取得できません。
どうしたらいいかご存知でしたら教えていただきたいです。
お返事お待ちしています。
ボタンを押せば動的テキストボックスの入力内容を(初期値だけでなく、変更した内容でも)ちゃんと取得してメッセージを表示してますよ。
動的なコントロールの作成ルーチンとAddHandlerで追加したClickイベントの内容をよく調べてください。
また、大事なのはFormロード時にもちゃんと動的コントロールを再作成しているということです。これをしないとポストバック時にはコントロールが無いことになります。
よく読まずに書き込みしてしまい、申し訳ありませんでした。すばやい返信にとても感謝しています。
再表示すれば簡単に取得できました、ありがとうございました。
動的のTable作成とコントロールの配置をしたかったので、大変参考になります。
ただ、まろんさんの書き込みにもありますが
動的に配置した内容を、ポストバック時に取得したいのですが、ポストバックと同時にコントロールが消えてしまい、取得できません。
例えば、「Button配置」のサンプルで
1.3×5のTable作成
2.行数を2に変更 (←どこもクリックはしない)
3.Tableの(3,5)位置のボタンをクリック
とするとポストバック時に行数が変わってしまったため、前の状態では取得できません。
やりたいことは、画面の条件(サンプルでは行数と列数)を変えた場合でも、画面に描画された時のイベントを発生させたいのですが、何か分かればご教授願います。
それを行うにはあらかじめ元の情報を別のHiddenコントロールなどに保持しておき、ポストバック時には元データで再作成しておき、イベント発生後に新しい行・桁数でテーブルを再作成するなどするしかないでしょう。
>あらかじめ元の情報を別のHiddenコントロールなどに保持しておき
そうですよね。
退避しないで、何かできるかと思っていたので甘かったです。。
自分がやりたいことが、別の方法でもできるかどうか検討したいと思います。
ありがとうございました。