【问题标题】:asp.net Can't find controls added from code-behind in a divasp.net 在 div 中找不到从代码隐藏添加的控件
【发布时间】:2014-02-15 06:42:51
【问题描述】:

我正在尝试访问 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 中。

有人知道为什么吗?

【问题讨论】:

  • 您在页面生命周期的哪个阶段添加了控件?如果是在页面初始化之后,则需要在每次回发后重新创建它们。
  • 实际上我在 page_preRender 中,现在我切换到 Page_Load 它工作。但是现在重新创建了控件 2...
  • 也许是一个很小的提示,但大多数程序员选择用英语编写所有代码,并且对于将来可能使您的某些代码更易于阅读的问题(例如,并非每个人都懂法语)。如果您的团队在未来的某一天获得国际成员,它也会变得更容易:)
  • 我知道 ^^ 实际上我的团队只由法国人组成,只有法国人可以访问代码,但我打算在发表评论和评论时用英文输入代码优化代码。实际上它更像是代码的粗略版本。

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


【解决方案1】:

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");

在页面类中声明为字段,然后在页面加载时添加它们,前提是页面不是回发;

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;
}

【讨论】:

  • 是的,我用 findControls 做到了,但我放了 3 * i 来测试我是否可以通过它的编号访问控件。
【解决方案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 文章中找到更多信息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-02-29
    • 2013-02-19
    • 1970-01-01
    • 2011-04-01
    • 2019-05-26
    • 1970-01-01
    • 1970-01-01
    • 2014-05-29
    相关资源
    最近更新 更多