- PR -

C#、ASP.NETでLINKBUTTONを動的に生成し、イベントを拾う方法

1
投稿者投稿内容
あんぐら
会議室デビュー日: 2005/04/29
投稿数: 2
お住まい・勤務地: 埼玉
投稿日時: 2005-04-29 15:37
こんにちは。

VisualStudioでWebフォームを作っているのですが、
C#側でtableを動的に生成して、
td内に他画面へのリンクボタンを動的に生成し、
C#内でリンククリックイベントを拾いたいのですが、
イベントが拾えません。

TABLEは一つと決まっているのですが、
リンクボタンは数が決まっていないので、
ASPのデザイン上にはコードを書いていません。

デザイン上にリンクボタンを書いた場合は、
イベントを拾えるのですが、
出力数が決まっていないので、書いていません。

何かいい方法はありますでしょうか。
下記にソースを載せましたので、
ご教授おねがいします。

[開発環境]
OS: windowsXP
統合環境: VisualStudio
使用言語: ASP.net(デザイン)
C#(ロジック)

[ソース]
// 自動生成
protected System.Web.UI.WebControls.Table Table1;
// 手書き
protected System.Web.UI.WebControls.LinkButton lb;

private void Page_Load(object sender, System.EventArgs e)
{
int numrows = 3;
int numcells = 3;

// TABLE生成
for (int j=0; j<numrows; j++)
{
TableRow r = new TableRow();
for (int i=0; i<numcells; i++)
{
TableCell c = new TableCell();
// リンクボタン
lb = new LinkButton();
lb.Text = "AAAAA";
lb.CommandName = "click";
lb.CommandArgument = "args";

c.Controls.Add(lb2);
c.BorderWidth = 1;
c.BorderColor = Color.Black;
r.Cells.Add(c);
}

Table1.Rows.Add(r);
}
}
// InitializeComponent
private void InitializeComponent()
{
this.lb.Click += new System.EventHandler(this.btn_click);
}
//クリックイベント
public void btn_click(object sender, System.EventArgs e)
{
// この中でリンクボタンの押下時処理;
}



[ メッセージ編集済み 編集者: あんぐら 編集日時 2005-04-29 15:39 ]
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2005-04-29 16:17
もうちょっと。

とりあえず、デバッガで、コードがどのように実行されているか、追っかけましょう。


あと、オブジェクトが一緒でなければならない、と言っておくと、大丈夫かな?
わからなければ、newは新しいオブジェクトを作るもの、というところに注意して、イベントを追加しているところと、いろいろ設定しているところが、同じイブじぇくと過注意してみてください。

もうひとつ、Page_Loadイベントハンドラメソッドのコメント「初期化」は、要注意です。
_________________
あんぐら
会議室デビュー日: 2005/04/29
投稿数: 2
お住まい・勤務地: 埼玉
投稿日時: 2005-04-30 10:23
Jittaさんありがとうございます。

返答遅れて申し訳ございません。
昨日Jittaさんのアドバイスを受け、
いろいろ試してみました。

ループ内で、newしているので
オブジェクトが初期化され、
イベントハンドルが出来ていなかったのですね。

たとえば、9個のリンクボタンのイベントを拾いたい場合は、

protected System.Web.UI.WebControls.LinkButton lb1;
protected System.Web.UI.WebControls.LinkButton lb2;

と9個分宣言して、
this.lb1.Click += new System.EventHandler(this.btn_click);
this.lb2.Click += new System.EventHandler(this.btn_click);

とイベントハンドルを行わないと
いけないという事が分かりました。

でも、そうなるとループ内でリンクボタンのテキストを変えたり
するのが出来ません・・。

リンクボタンを使う数も決まってないので、悩ましいところです。
何とか動的にリンクボタンの数を増やしたり、出来ないものですかね。

以下は、3つのリンクボタンを同列に埋め込む処理です。
[ソース]
// 自動生成
protected System.Web.UI.WebControls.Table Table1;
// 手書き
protected System.Web.UI.WebControls.LinkButton lb1;
protected System.Web.UI.WebControls.LinkButton lb2;
protected System.Web.UI.WebControls.LinkButton lb3;

private void Page_Load(object sender, System.EventArgs e)
{
int numrows = 3;
int numcells = 3;

// リンクボタン
lb1.Text = "AAAAA";
lb1.CommandArgument = "args1";
lb2.Text = "BBBBB";
lb2.CommandArgument = "args2";
lb3.Text = "CCCCC";
lb3.CommandArgument = "args3";

// TABLE生成
for (int j=0; j<numrows; j++)
{
TableRow r = new TableRow();
for (int i=0; i<numcells; i++)
{
TableCell c = new TableCell();

if (j == 0)
{
c.Controls.Add(lb1);
}
else if (j == 1)
{
c.Controls.Add(lb2);
}
else
{
c.Controls.Add(lb3);
}

c.BorderWidth = 1;
c.BorderColor = Color.Black;
r.Cells.Add(c);
}

Table1.Rows.Add(r);
}
}
// InitializeComponent
private void InitializeComponent()
{
this.lb1.Click += new System.EventHandler(this.btn_click);
this.lb2.Click += new System.EventHandler(this.btn_click);
this.lb3.Click += new System.EventHandler(this.btn_click);
}
//クリックイベント
public void btn_click(object sender, System.EventArgs e)
{
// この中でリンクボタンの押下時処理;
}
NAL-6295
ぬし
会議室デビュー日: 2003/01/26
投稿数: 966
お住まい・勤務地: 東京
投稿日時: 2005-04-30 12:41
Repeaterコントロールだっけ。
とかを利用するという手もあります。
burton999
ぬし
会議室デビュー日: 2003/10/06
投稿数: 898
お住まい・勤務地: 東京
投稿日時: 2005-05-01 00:17
コード:
for (int j=0; j<numrows; j++)
{
	TableRow r = new TableRow();
	for (int i=0; i<numcells; i++)
	{
		TableCell c = new TableCell();
		LinkButton lb = new LinkButton();
		lb.Text = "AAAAA";
		lb.CommandArgument = "args" + i.ToString(); 
		lb.Click += new System.EventHandler(this.btn_click);
		
		c.Controls.Add(lb);
		c.BorderWidth = 1;
		c.BorderColor = Color.Black;
		r.Cells.Add(c);
	}

	Table1.Rows.Add(r);
}



こんな感じでできないですかね?
動作確認してないですけど。。。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2005-05-01 06:07
 えっと、ソースコードを載せられても、困ります。読むのがしんどいですから。
 最初の投稿でも、Initializeでイベント追加をして、loadでオブジェクト生成しているということしか読んでいません。
 なので、コードがどのように実行されるか確認しましょう。オブジェクトは1つでなければなりません。という助言をしました。プログラムはInitialize→Loadの順で実行され、Initializeで追加したイベントが消されるからです。
(または、別のオブジェクトに対してイベントが定義される)

 まず、そのことはクリアされ・・てますね?LinkButtonの生成が無くなっていますが、なぜでしょう?.aspxに貼り付けたコントロールは、.aspx.??では生成する必要がありません。.aspxの方で生成されるからです。

 そうすると、これは動的な生成ではなく、静的な生成ですね。

 動的に生成する方法は、MSDNやKBで紹介されていますし、ここの過去ログにもたくさんあります。
 ひとつはburton999さんのように、宣言はせず、宣言が無くても発生するイベントで処理する方法。イベントはClickではなく、Commandだったかな?の方に追加するようにして、IDも宣言すれば動くと思います。
 ひとつは、Initializeでオブジェクトの生成と、コントロール階層への追加を行う方法。
 どちらも、.aspxファイルにはコントロールを配置しません。
 NAL-6295さんのRepeaterコントロールは、テンプレートを1つ宣言して、それを任意の数だけ繰り返す(Repeat)というものです。
 あるいは、DataGridも、HTML上ではtable要素ですので、これが使えるかもしれません。

 どの方法が適切かは、どのような見え方を望むのか、などの条件によって変わります。時間がゆるすなら、一つ一つ確認してみてください。
1

スキルアップ/キャリアアップ(JOB@IT)