2011-07-31 38 views
2

最近問題一直在困擾我。我希望你能幫助我。如何將動態創建的按鈕添加到動態創建的表格中?

我想在用戶單擊按鈕後創建一個表。在第一個單元格的每一行上,我想添加一個按鈕。不幸的是,表格按鈕無法觸發事件。你能告訴我怎麼做,或者我的錯誤在哪裏?我已使用this article創建以下示例代碼。

<asp:PlaceHolder ID="placeHolderForTable" runat="server"> 

</asp:PlaceHolder> 
<asp:Button ID="btnCreateTbl" runat="server" Text="Create Table"/> 
<asp:Label ID="lblResult" runat="server" /> 

代碼:

private struct ControlInfo 
{ 
    public string ID; 
    public string Type; 
    public int Border; 
    public HtmlTableRow[] TblRows; 
    public HtmlTableCell[] TblCells; 
    public int Width; 
    public int Height; 
} 


protected void Page_Load(object sender, EventArgs e) 
{ 
    btnCreateTbl.Click+=new EventHandler(BtnClick); 
    if (this.IsPostBack) this.RecreatePersistedControls(); 
}//end Page_Load 


//Call CreateControl for each persisted control 
private void RecreatePersistedControls() 
{ 
    ArrayList al = (ArrayList)this.Session["DynamicControls"]; 
    if (al != null) 
     foreach (ControlInfo ci in al) 
      this.CreateControl(ci); 
}//end RecreatePersisterdControls method 

//Create control specified by ControlInfo structure 
private Control CreateControl(ControlInfo ci) 
{ 
    Control ctl = null; 

    switch (ci.Type) 
    { 
     case "Button": 
      ctl = new Button(); 
      ctl.ID = ci.ID; 
      ((Button)ctl).Text = "Edit"; 
      ((Button)ctl).Click+=new EventHandler(this.DoNothing); 
      if (this.placeHolderForTable.FindControl("tblResult") != null) 
      { 
       for (int r = 0; r < ci.Height; r++) 
       { 
        if (this.placeHolderForTable.FindControl("tblResult").FindControl("tr" + (r + 1)) != null && (r+1).ToString()==ci.ID[7].ToString()) 
         if (this.placeHolderForTable.FindControl("tblResult").FindControl("tr" + (r + 1)).FindControl("td" + (r + 1) + "1") != null) 
          if(this.placeHolderForTable.FindControl("tblResult").FindControl("tr" + (r + 1)).FindControl("td" + (r + 1) + "1").FindControl(ctl.ID)==null) 
           this.placeHolderForTable.FindControl("tblResult").FindControl("tr" + (r + 1)).FindControl("td" + (r + 1) + "1").Controls.Add(ctl); 
       } 
      } 
      break; 
     case "HtmlTable": 
      ctl = new HtmlTable(); 
      ctl.ID = ci.ID; 
      ((HtmlTable)ctl).Border = ci.Border; 

      for (int r = 0; r < ci.Height; r++) 
      { 
       HtmlTableRow row = ci.TblRows[r]; 
       row.ID = "tr" + (r + 1); 
       for (int c = r * ci.Width; c < r * ci.Width+2; c++) 
       { 
        ci.TblCells[c].ID="td"+(r+1)+(c%2+1); 
        row.Cells.Add(ci.TblCells[c]); 

       } 
       ((HtmlTable)ctl).Rows.Add(row); 
      } 
      if(this.placeHolderForTable.FindControl(ctl.ID)==null) 
       this.placeHolderForTable.Controls.Add(ctl); 
      break; 
     default: 
      return null; 
    } 
    return ctl; 
}//end CreateControl method 

//Create ControlInfo structure and persist it to Session 
private ControlInfo PersistControl(string id, string type, int border, HtmlTableRow[] tblRows, HtmlTableCell[] tblCells, int width, 
    int height) 
{ 
    ControlInfo ci = new ControlInfo(); 
    ci.ID = id; 
    ci.Type = type; 
    ci.Border = border; 
    ci.TblRows = tblRows; 
    ci.TblCells = tblCells; 
    ci.Width = width; 
    ci.Height = height; 

    ArrayList al = (ArrayList)this.Session["DynamicControls"]; 
    if (al == null) al = new ArrayList(); 
    al.Add(ci); 
    this.Session["DynamicControls"] = al; 
    return ci; 
}//end PersistControl method 

private void BtnClick(object sender, EventArgs e) 
{ 
    int cellIx=0,rowIx=0;    
    HtmlTableRow tr1 = new HtmlTableRow(); 
    HtmlTableCell td11 = new HtmlTableCell(); 
    tr1.Cells.Add(td11); 
    HtmlTableCell td12 = new HtmlTableCell(); 
    td12.InnerText = "td12"; 
    tr1.Cells.Add(td12); 
    HtmlTableRow tr2 = new HtmlTableRow(); 
    HtmlTableCell td21 = new HtmlTableCell(); 
    tr2.Cells.Add(td21); 
    HtmlTableCell td22 = new HtmlTableCell(); 
    tr2.Cells.Add(td22); 
    td22.InnerText = "td22"; 
    HtmlTableRow []arrRows=new HtmlTableRow[2]; 
    arrRows[rowIx++]=tr1; 
    arrRows[rowIx++]=tr2; 
    HtmlTableCell []arrCells=new HtmlTableCell[4]; 
    arrCells[cellIx++]=td11; 
    arrCells[cellIx++]=td12; 
    arrCells[cellIx++]=td21; 
    arrCells[cellIx++]=td22; 
    ControlInfo ci = PersistControl("tblResult", "HtmlTable", 3, arrRows, arrCells, 2, 2); 
    HtmlTable tblResult = (HtmlTable)CreateControl(ci); 

    ci = PersistControl("btnEdit1", "Button", 0, arrRows, arrCells, 2, 2); 
    Button btnEdit1 = (Button)CreateControl(ci); 

    ci = PersistControl("btnEdit2", "Button", 0, arrRows, arrCells, 2, 2); 
    Button btnEdit2 = (Button)CreateControl(ci); 
} 

public void DoNothing(object sender, EventArgs e) 
{ 
    lblResult.Text = (sender as HtmlButton).ID + " done"; 
} 
+0

我知道這是不是一個特別有建設性的意見,但我會用這個職位作爲微軟爲什麼是正確的引進ASP的例子。 NET MVC(以及爲什麼WebForms不應該存在)! –

+0

按照你的意願去做。 – Pepe

回答

0

動態控制是整個其他的野獸,我儘量遠離他們儘可能多地。這就是說,有些情況下他們可能是必要的。

有關事件處理程序和動態控制的東西,你必須確保要連接和控件添加到在OnInit或Page_Load中的功能,頁面控制樹不然就行爲怪異http://support.microsoft.com/?id=317794

我做對您的代碼進行一些編輯,將Page_Load中的事件處理程序連接起來。見下面,讓我知道,如果你有任何問題:

// Added a ViewState persisted prop 
    bool WireUpControls 
    { 
     get 
     { 
      return ViewState["wireUpControls"] != null ? Convert.ToBoolean(ViewState["wireUpControls"]) : false; 
     } 
     set 
     { 
      ViewState["wireUpControls"] = value; 
     } 
    } 

    void CreateControlTable() 
    { 
     int cellIx = 0, rowIx = 0; 
     HtmlTableRow tr1 = new HtmlTableRow(); 
     HtmlTableCell td11 = new HtmlTableCell(); 
     tr1.Cells.Add(td11); 
     HtmlTableCell td12 = new HtmlTableCell(); 
     td12.InnerText = "td12"; 
     tr1.Cells.Add(td12); 
     HtmlTableRow tr2 = new HtmlTableRow(); 
     HtmlTableCell td21 = new HtmlTableCell(); 
     tr2.Cells.Add(td21); 
     HtmlTableCell td22 = new HtmlTableCell(); 
     tr2.Cells.Add(td22); 
     td22.InnerText = "td22"; 
     HtmlTableRow[] arrRows = new HtmlTableRow[2]; 
     arrRows[rowIx++] = tr1; 
     arrRows[rowIx++] = tr2; 
     HtmlTableCell[] arrCells = new HtmlTableCell[4]; 
     arrCells[cellIx++] = td11; 
     arrCells[cellIx++] = td12; 
     arrCells[cellIx++] = td21; 
     arrCells[cellIx++] = td22; 
     ControlInfo ci = PersistControl("tblResult", "HtmlTable", 3, arrRows, arrCells, 2, 2); 
     HtmlTable tblResult = (HtmlTable)CreateControl(ci); 

     ci = PersistControl("btnEdit1", "Button", 0, arrRows, arrCells, 2, 2); 
     Button btnEdit1 = (Button)CreateControl(ci); 

     ci = PersistControl("btnEdit2", "Button", 0, arrRows, arrCells, 2, 2); 
     Button btnEdit2 = (Button)CreateControl(ci); 
    } 

    // Call CreateControlTable() if we need to create the controls and wire up events 
    protected void Page_Load(object sender, EventArgs e) 
    { 
     btnCreateTbl.Click += new EventHandler(BtnClick); 
     if (WireUpControls) CreateControlTable(); 
     //if (this.IsPostBack) this.RecreatePersistedControls(); 

    } 

    protected void BtnClick(object sender, EventArgs e) 
    { 
     WireUpControls = true; 
     CreateControlTable(); 
    } 

    public void DoNothing(object sender, EventArgs e) 
    { 
     lblResult.Text = (sender as Button).ID + " done"; 
    } 
+0

非常感謝您的回答。但是,表格中的按鈕仍然不會觸發「DoNothing」事件。 – Pepe

+0

調試顯示WireUpControls始終返回「false」。 – Pepe

+0

啊哈。 ViewState [「wireUpControls」]必須在BtnClick事件中(在表的初始創建時)設置爲true。 – Pepe