2011-12-21 2 views
4

Я пытаюсь создать приложение, добавляющее динамические контроллеры. У меня есть MasterPage, мой жерех: Содержание здесь:FindControl() return 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" /> 

После нажатия на btnAdd Я хочу добавить два текстовых полей. Я стараясь сделать это как в 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 Еогеаспе ищет мой btnAdd, например, в первой итерации для ЕГО «ctl00 $ MainContent $ scriptManager1 ", myControl равно null ... В следующих итерациях также ... Так что моя функция всегда возвращает значение null. Что может быть причиной?

ответ

8

FindControl только ищет прямых детей контейнера. Поскольку вы начинаете с уровня страницы, вам необходимо будет пройти через контролер UpdatePanel ребенка, чтобы добраться до вашего btnAdd.

Посмотрите here для примера, как это сделать.

Edit: Я не уверен, я понимаю, почему вы «ищете» для кнопки такого способа, так как есть только один статические кнопки на экране - вам не нужно будет использовать FindControl в этом дело.

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

(или в коде, btnAdd.OnClick += new EventHandler(btnAdd_Click);)

Даже если у вас несколько кнопок в вашей форме добавлены динамически, вы можете подключить все из них до того же кнопок Click обработчика, в этом случае sender бы тогда нажмите кнопку управления кнопкой. Обычно вы используете FindControl для очистки данных из динамически добавленных элементов управления вводами (текстовое поле и т. Д.), А не для того, чтобы увидеть, какой элемент управления вызвал Postback (поскольку «отправитель» в соответствующем обработчике событий будет проще)

Изменить 2: вы можете добавить кнопки динамически так же, как ваши другие элементы управления

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

Если вы хотите, чтобы все элементы управления, которые вы добавили уже «пребывания» между постбэков затем включить ViewState на странице и элементы управления, а затем убедитесь, что вы только добавили элементы управления один раз без обратной передачи, в OnInit:

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

Вы можете сохранить состояние «mycount» в скрытом поле (в том же обновлении и с включенным viewstate) - вам нужно будет разобрать его на int каждый раз. Или вы можете использовать SessionState для его отслеживания.

+0

Благодарим вас за ответ! Позже я добавлю здесь вторую статическую кнопку, динамически будет здесь только текстовые поля. Итак, вы думаете, что я могу использовать здесь btnAdd_Click()? Я понятия не имею, как это сделать в кнопке, чтобы увеличить myCount, а затем перезагрузить страницу с новым значением на myCount. О чем вы думаете? – cadi2108