我试图访问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é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中。
有人知道为什么吗?
答案 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;
}