• 締切済み

動的に生成したボタンのイベントが拾えない

環境は、Visual Web Developer 2008 Express Editon with C# です。 データベースは、Oracle 10g Express Edition です。 触り始めて、1週間程度ですので、お手やらかに。 次のようなコードで、Oracleから取得した値をテーブルに表示しています。ここでreaderは、System.Data.OracleClient.OracleDataReaderラスのオブジェクト、Menuは、System.Web.UI.WebControls.Tableクラスのオブジェクトです。 while (reader.Read()) {   object[] values = new object[3];   int i = reader.GetOracleValues(values);   TableRow r = new TableRow();   TableCell delcom = new TableCell();   Button delButton = new Button();   delButton.Click += new EventHandler(delButton_Click);   delButton.Text = "削除";   delcom.Controls.Add(delButton);   r.Cells.Add(delcom);   for (int j = 0; j < 3; j++)   {     TableCell cell = new TableCell();     cell.Text = values[j].ToString();     r.Cells.Add(cell);   }   Menu.Rows.Add(r); } このコードは、メソッドにして、Page_Loadおよび、delButton_Clickの両メソッドから呼び出しています。 ここで、各行に貼り付けた「削除」ボタンを押すと、1回目では削除されず、2回目で削除されるという現象が起きています。 デバッガで追うと、1回目はdelButton_Clickメソッドが呼ばれず、2回目では呼ばれています。 1回目の表示では、設定したイベントが 色々、調べてみましたが、ちょっとお手上げです。 どのようにすれば、毎回この設定したイベントが有効になるかお知恵を拝借できないでしょうか? よろしくお願いします。

みんなの回答

  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.2

当方 VS2005なのですが 動的に作成したボタンイベントも1回目でハンドラへ来ますよ 当方で実験したコードは以下のような感じです データベースを使わずに 無条件で10個のボタンを作成します PageのViewStateを使って表示/非表示を切り替えます protected void Page_Load(object sender, EventArgs e) {   for (int n = 0; n < 10; n++)   {     TableRow r = new TableRow();     TableCell c = new TableCell();     Button btn;     string ss = String.Format("del{0,2:d}", n);     btn = new Button();     btn.Text = ss;     btn.Font.Name = Table1.Font.Name;     btn.Font.Size = Table1.Font.Size;     btn.Click += new EventHandler(myClick);     if (IsPostBack && !ViewState.IsItemDirty(ss))     {       // ポストバック時にViewStateにアイテムが無いなら非表示       btn.Visible = false;       c.Visible = false;       r.Visible = false;     }     c.Controls.Add(btn);     r.Controls.Add(c);     Table1.Controls.Add(r);     if (!IsPostBack)     {       // 初回のみViewStateに登録       ViewState[ss] = ss;     }   } } protected void myClick(object sender, EventArgs e) {   Button btn = (Button)sender;   // ViewStateからアイテムを削除   ViewState.Remove(btn.Text);   // コントロールを削除   Table1.Controls.Remove(btn.Parent.Parent); } といった具合です PageLoad時に ViewStateを見てコントロールの作成自体をスキップするコードにすると Clickイベントの引数senderがおかしくなる現象が起きました たとえば 3番目の『del 2』を削除した後『del 3』を削除しようとした場合『del 4』を削除してしまいます ここでもう一度『del 3』をクリックすると『del 3』が削除される といった現象です GridViewを使ったほうが簡単に実現出来そうですよ

masa6272
質問者

お礼

やはり、無理でした。 リンクの生成のタイミングですね。 何か、うまい方法を考えます。

  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.1

データベースを介さずに単純に ボタンだけを動的に生成した場合は 『delButton_Click』への到達は1回目で可能なのか確かめましょう

関連するQ&A