asp.net无法在div中找到从代码隐藏中添加的控件

时间:2014-01-24 10:09:43

标签: c# asp.net html code-behind

我试图访问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>

但是当我尝试从后面的代码中添加控件时,它表示值为null。

    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中。

有人知道为什么吗?

2 个答案:

答案 0 :(得分:2)

动态添加控件时,您需要确保在每次回发后重新创建这些控件。

在.aspx文件中声明控件和从代码后面以编程方式添加它们之间存在差异:

以声明方式添加控件,然后所有控件都在未来的回发中,因为在每个回发请求中,ASP.NET Webforms使用设计器中的声明和数据重新创建页面的状态来自Viewstate和发布的表单。

当以编程方式添加控件时,ASP.NET将尝试执行相同操作:使用.aspx文件+ ViewState +已发布表单中的声明重新创建服务器上页面的状态。它没有办法知道你已经修改了Controls层次结构,并且你已经添加或删除了一些控件,因为在回发之间不会以任何方式跟踪这些更改。这就是为什么您需要在每次回发时重新创建预期的层次结构。

您需要重新运行代码,以便在 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);
}

您可以在ASP.NET Page Life Cycle文章上找到有关MSDN的更多信息。

答案 1 :(得分: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;
}