2014-01-24 33 views
1

我試圖訪問div中的控件,但我找不到它們。asp.net無法找到從代碼隱藏在div中添加的控件

我得到了一個div中的一些控件。

<div id="divChampsFiltrageProjetsTest" class="divChampsFiltrageProjetsTest" runat="server"> 

    <span runat="server" style="color:black;"> Filtre 1 : </span> 
    <asp:DropDownList ID="ddlFiltreProjets1" runat="server" ForeColor="Black" > 
    <asp:ListItem Value="no" Selected="True">No. Projet</asp:ListItem> 
    <asp:ListItem Value="desi">Designation Projet</asp:ListItem> 
    <asp:ListItem Value="chef">Chef de Projet</asp:ListItem> 
    </asp:DropDownList> 

    <asp:TextBox ID="txtValeurFiltreProjets1" runat="server" ForeColor="Black" /> 

    <asp:Button ID="btnAddFiltre1" runat="server" Text="Ok" OnClick="btnAppliquerFiltreProjets_Click"/> 

</div> 

我可以在後面的代碼中找到這些控件。但是,當我從後面的代碼中添加一些控件時會出現問題。

  HtmlGenericControl span = new HtmlGenericControl("span"); 
      DropDownList ddlList = new DropDownList(); 
      TextBox txtValeur = new TextBox(); 
      Button btnAdd = new Button(); 
      ListItem item1 = new ListItem("No. Projet", "no"); 
      ListItem item2 = new ListItem("Désignation Projet", "desi"); 
      ListItem item3 = new ListItem("Chef de Projets", "chef"); 

      span.Style.Add(HtmlTextWriterStyle.Color, "Black"); 
      span.InnerText = "Filtre " + (i + 1).ToString() + " : "; 

      ddlList.ID = "ddlFiltreProjets" + (i + 1).ToString(); 
      ddlList.Items.Add(item1); 
      ddlList.Items.Add(item2); 
      ddlList.Items.Add(item3); 

      txtValeur.ID = "txtValeurFiltreProjets" + (i + 1).ToString(); 
      txtValeur.ForeColor = System.Drawing.Color.Black; 

      btnAdd = btnAddFiltre1; 

      divChampsFiltrageProjetsTest.Controls.Add(span); 
      divChampsFiltrageProjetsTest.Controls.Add(ddlList); 
      divChampsFiltrageProjetsTest.Controls.Add(txtValeur); 
      divChampsFiltrageProjetsTest.Controls.Add(btnAdd); 

這部分代碼將控件添加到div,當我得到頁面時,控件位於源代碼中。

 <div id="MainContent_divChampsFiltrageProjets" class="divChampsFiltrageProjets" style="display:block;"> 
      <div id="MainContent_divChampsFiltrageProjetsTest" class="divChampsFiltrageProjetsTest"> 

       <span style="color:black;"> Filtre 1 : </span> 
       <select name="ctl00$MainContent$ddlFiltreProjets1" id="MainContent_ddlFiltreProjets1" style="color:Black;"> 
<option value="no">No. Projet</option> 
<option value="desi">Designation Projet</option> 
<option selected="selected" value="chef">Chef de Projet</option> 

</select> 

       <input name="ctl00$MainContent$txtValeurFiltreProjets1" type="text" value="johan" id="MainContent_txtValeurFiltreProjets1" style="color:Black;" /> 

      <span style="color:Black;">Filtre 2 : </span><select name="ctl00$MainContent$ddlFiltreProjets2" id="MainContent_ddlFiltreProjets2"> 
<option value="no">No. Projet</option> 
<option value="desi">D&#233;signation Projet</option> 
<option value="chef">Chef de Projets</option> 

</select><input name="ctl00$MainContent$txtValeurFiltreProjets2" type="text" id="MainContent_txtValeurFiltreProjets2" style="color:Black;" /><input type="submit" name="ctl00$MainContent$btnAddFiltre1" value="Ok" id="MainContent_btnAddFiltre1" /></div> 

但是,當我試圖讓我從代碼後面加它說,該值是空的控件。

for (int i = 1; i < Convert.ToInt32(Session["nbFiltres"].ToString()) + 1; i++) 
    { 

     DropDownList ddl = (DropDownList)divChampsFiltrageProjetsTest.FindControl("ddlFiltreProjets"+i.ToString()); 
     TextBox txt = (TextBox)divChampsFiltrageProjetsTest.FindControl("txtValeurFiltreProjets" +i.ToString()); 

     Session["typeFiltreProjets" + i.ToString()] = ddl.SelectedValue.ToString(); 
     Session["valeurFiltreProjets" + i.ToString()] = txt.Text; 
    } 

這部分是在一個按鈕的點擊事件函數。

所以我的問題是,我從代碼後面添加的控件不是真的在div中。

有人知道爲什麼嗎?

+0

您在頁面生命週期的哪個點添加了控件?如果它是在頁面初始化之後,那麼在每次回發後都需要重新創建它們。 – Paddy

+0

實際上我在page_preRender中,現在我切換到Page_Load它工作。但現在重新創建控件2 ... –

+1

也許是一個非常小的提示,但大多數程序員選擇用英文編碼所有內容,並且對於將來可能會使代碼的某些部分更容易閱讀的問題(不是每個人都知道法語,例如)。如果你的團隊在未來的某一天獲得國際成員,它也會變得更容易:) –

回答

2

當添加控件動態,你需要確保這些被重新創建之後各回發。

有在.aspx文件中聲明控件和編程代碼從加入他們身後之間的差異:當控件添加聲明那麼所有的控件都沒有對未來的回傳

,因爲在每一個回傳請求ASP.NET Webforms使用設計器中的聲明以及Viewstate和發佈表單中的數據重新創建頁面的狀態。

當以編程方式將控件添加到時,ASP.NET將嘗試執行相同的操作:使用.aspx文件+ ViewState +張貼表單中的聲明重新創建服務器上的頁面狀態。它無法知道您修改了控件層次結構,並且您已添加或刪除了一些控件,因爲這些更改在回發之間未以任何方式進行跟蹤。這就是爲什麼您需要在每次回發時重新創建預期層次結構的原因。

您將需要重新運行代碼,該代碼在Page_Init事件中添加控件。這很重要,因爲在此事件發生後,ASP.NET將嘗試將狀態信息從ViewState和發佈的數據綁定到控件層次結構,現在它將包含您的動態控件。如果您不這樣做,您仍然擁有您的控件,但是您將無法檢索用戶在這些控件上發佈的數據。

這裏是你的代碼可能看起來怎麼樣:

public void Page_Init(object sender, EventArgs e){ 
    CreateDynamicControls(); 
} 

public void CreateDynamicControls(){ 
    HtmlGenericControl span = new HtmlGenericControl("span"); 
    DropDownList ddlList = new DropDownList(); 
    TextBox txtValeur = new TextBox(); 
    Button btnAdd = new Button(); 
    ListItem item1 = new ListItem("No. Projet", "no"); 
    ListItem item2 = new ListItem("Désignation Projet", "desi"); 
    ListItem item3 = new ListItem("Chef de Projets", "chef"); 

    span.Style.Add(HtmlTextWriterStyle.Color, "Black"); 
    span.InnerText = "Filtre " + (i + 1).ToString() + " : "; 

    ddlList.ID = "ddlFiltreProjets" + (i + 1).ToString(); 
    ddlList.Items.Add(item1); 
    ddlList.Items.Add(item2); 
    ddlList.Items.Add(item3); 

    txtValeur.ID = "txtValeurFiltreProjets" + (i + 1).ToString(); 
    txtValeur.ForeColor = System.Drawing.Color.Black; 

    btnAdd = btnAddFiltre1; 

    divChampsFiltrageProjetsTest.Controls.Add(span); 
    divChampsFiltrageProjetsTest.Controls.Add(ddlList); 
    divChampsFiltrageProjetsTest.Controls.Add(txtValeur); 
    divChampsFiltrageProjetsTest.Controls.Add(btnAdd); 
} 

你可以找到在MSDN上的詳細信息,在ASP.NET Page Life Cycle文章。

+0

謝謝你的工作! –

+0

不客氣,我很高興我可以幫助:) – Lucian

0

divChampsFiltrageProjetsTest.Controls[3 * i];不看的權利也許你應該嘗試的FindControl代替

for (int i = 1; i < Convert.ToInt32(Session["nbFiltres"].ToString()) + 1; i++) 
    { 

     DropDownList ddl = (DropDownList)divChampsFiltrageProjetsTest.FindControl("ddlFiltreProjets" + (i + 3 * i).ToString()); 
     TextBox txt = (TextBox)divChampsFiltrageProjetsTest.FindControl("txtValeurFiltreProjets" + (5 * i).toString()); 

     Session["typeFiltreProjets" + i.ToString()] = ddl.SelectedValue.ToString(); 
     Session["valeurFiltreProjets" + i.ToString()] = txt.Text; 
    } 

你可以做的是有

HtmlGenericControl span = new HtmlGenericControl("span"); 
    DropDownList ddlList = new DropDownList(); 
    TextBox txtValeur = new TextBox(); 
    Button btnAdd = new Button(); 
    ListItem item1 = new ListItem("No. Projet", "no"); 
    ListItem item2 = new ListItem("Désignation Projet", "desi"); 
    ListItem item3 = new ListItem("Chef de Projets", "chef"); 
聲明爲Page類領域

然後加入他們的提供頁面的頁面加載不是回發;

public override void OnLoad(../*cant' remember the parameters*/){ 
    if(!Page.IsPostBack){ 
     span.Style.Add(HtmlTextWriterStyle.Color, "Black"); 

     span.InnerText = "Filtre " + (i + 1).ToString() + " : "; 

     ddlList.ID = "ddlFiltreProjets" + (i + 1).ToString(); 
     ddlList.Items.Add(item1); 
     ddlList.Items.Add(item2); 
     ddlList.Items.Add(item3); 

     txtValeur.ID = "txtValeurFiltreProjets" + (i + 1).ToString(); 
     txtValeur.ForeColor = System.Drawing.Color.Black; 

     btnAdd = btnAddFiltre1; 

     divChampsFiltrageProjetsTest.Controls.Add(span); 
     divChampsFiltrageProjetsTest.Controls.Add(ddlList); 
     divChampsFiltrageProjetsTest.Controls.Add(txtValeur); 
     divChampsFiltrageProjetsTest.Controls.Add(btnAdd); 

那麼你應該能夠只使用他們在點擊事件

for (int i = 1; i < Convert.ToInt32(Session["nbFiltres"].ToString()) + 1; i++) 
{ 

    Session["typeFiltreProjets" + i.ToString()] = ddlList.SelectedValue.ToString(); 
    Session["valeurFiltreProjets" + i.ToString()] = txtValeur.Text; 
} 
+0

是的,我用findControls做了它,但是我把3 * i來測試它是否可以通過它的編號訪問控件。 –

相關問題