2011-12-21 70 views
4

我試圖創建應用程序whad添加controlls dynamicaly。我有母版,我的ASP:內容是在這裏:在btnAdd點擊FindControl()返回null

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"> 
<asp:ScriptManager ID="scriptManager1" runat="server"> 
</asp:ScriptManager> 
<div style="margin: 10px"> 
    <asp:UpdatePanel ID="updatePanel1" runat="server"> 
     <ContentTemplate> 
      <asp:PlaceHolder runat="server" ID="myPlaceHolder" /> 
     </ContentTemplate> 
     <Triggers> 
      <asp:AsyncPostBackTrigger ControlID="btnAdd" EventName="Click" /> 
     </Triggers> 
    </asp:UpdatePanel> 
</div> 
<asp:Button ID="btnAdd" runat="server" Text="Add" /> 

後,我想添加兩個文本框。我想做到像在http://jagdeepmankotia.wordpress.com/2010/01/30/dynamically-add-controls-in-asp-net-c/

這是我的代碼:

static int myCount = 1; 
    private TextBox[] color; 
    private TextBox[] text; 

    protected override void OnInit(EventArgs e) 
    { 
     base.OnInit(e); 
     color = new TextBox[myCount]; 
     text = new TextBox[myCount]; 

     for (int i = 0; i < myCount; i++) 
     { 
      TextBox tbColor = new TextBox(); 
      tbColor.ID = "colorTextBox" + i.ToString(); 
      myPlaceHolder.Controls.Add(tbColor); 
      color[i] = tbColor; 

      TextBox tbText = new TextBox(); 
      tbText.ID = "textTextBox" + i.ToString(); 
      myPlaceHolder.Controls.Add(tbText); 
      text[i] = tbText; 

      LiteralControl literalBreak = new LiteralControl("<br />"); 
      myPlaceHolder.Controls.Add(literalBreak); 
     } 
    } 


    public Control GetPostBackControl(Page page) 
    { 
     Control control = null; 
     string ctrlname = page.Request.Params.Get("__EVENTTARGET"); 
     if (ctrlname != null && ctrlname != string.Empty) 
     { 
      control = page.FindControl(ctrlname); 
     } 
     else 
     { 
      foreach (string ctl in page.Request.Form) 
      { 
       Control mycontrol = page.FindControl(ctl); 
       if (mycontrol is System.Web.UI.WebControls.Button) 
       { 
        control = mycontrol; 
        // This gives you ID of which button caused postback       
        break; 
       } 
      } 
     } 
     return control; 
    } 

    protected void Page_PreInit(object sender, EventArgs e) 
    { 
     Control myControl = GetPostBackControl(this.Page); 
     if (myControl != null) 
      if (myControl.ClientID.ToString() == "btnAdd") 
       myCount = myCount + 1; 
    } 

    protected void btnAdd_Click(object sender, EventArgs e) 
    { 
     //handled in PreInit  

    } 

當函數GetPostBackControl()在loap的foreach找我btnAdd,例如在點擊率「ctl00 $搜索Maincontent $ scriptManager1第一次迭代「,myControl爲空......在下一次迭代中也是......所以我的函數總是返回null。什麼是理由?

回答

8

FindControl只搜索容器的直接子項。由於您是在頁面級開始的,因此您需要通過子項UpdatePanel遞歸控制才能訪問您的btnAdd控件。

看看here舉例說明如何做到這一點。

編輯: 我不知道我理解你爲什麼你以這種方式按鈕「尋找」,因爲只有一個在屏幕上的靜態按鈕 - 你就不需要在此使用FindControl案件。

<asp:Button ID="btnAdd" runat="server" Text="Add" onclick="btnAdd_Click" /> 

(或代碼,btnAdd.OnClick += new EventHandler(btnAdd_Click);

即使你已經在你的表單多個按鈕動態添加,你可以連接所有他們到同一個按鈕單擊處理程序,在這種情況下sender然後會包含被點擊的按鈕控件。您通常會使用FindControl來從動態添加的輸入控件(文本框等)中刪除數據,而不是查看哪個控件導致回發(因爲適當事件處理程序中的「發件人」會更容易)

編輯2: 您可以添加按鈕動態就像你的其他控件

Button myButton = new Button(); 
    myButton.Text = "Click Me"; 
    myButton.Click += new EventHandler(btnAdd_Click); 
    myPlaceHolder.Controls.Add(myButton); 

如果你想,你已經回發之間已經加入到「留」在所有控件然後啓用視圖狀態的頁面和控件,然後確保在OnInit中只添加一次控件而不回發:

base.OnInit(e);  
    if (!IsPostBack) 
    { // ... Add controls here 

您可以將'mycount'狀態保留在隱藏字段中(在同一個updatepanel中,並且啓用viewstate) - 每次需要將其解析爲int。或者你可以使用SessionState來跟蹤它。

+0

謝謝你的回答!稍後我會在這裏添加第二個靜態按鈕,動態地將這裏只有文本框。所以你認爲我可以在這裏使用btnAdd_Click()?我不知道,我怎樣才能在按鈕中增加myCount,然後用myCount上的新值重新加載頁面。你有什麼想法? – cadi2108 2011-12-21 13:43:38