我无法在ListView中获取动态创建的控件的输入值。
这是我的ListView:
<asp:ListView ID="lvQuestions" runat="server" DataKeyNames="ProductQuestionId" onitemdatabound="lvQuestions_ItemDataBound">
<LayoutTemplate>
<table>
<tr runat="server" id="itemPlaceholder"></tr>
</table>
</LayoutTemplate>
<ItemTemplate>
<tr>
<td><%# Eval("Question") %></td>
<td>
<asp:PlaceHolder ID="plControl" runat="server" />
<asp:HiddenField ID="hfQuestionId" runat="server" />
</td>
</tr>
</ItemTemplate>
</asp:ListView>
<asp:Button ID="btnSubmit" runat="server" Text="Submit" onclick="btnSubmit_Click" />
在我的ItemDataBound处理程序中,我将一个TextBox或其他控件添加到占位符。控件类型取决于项目,但为了保持简单,我们假设它始终是一个文本框。控件的ID也是动态的。
// create a textbox control
TextBox txtbx = new TextBox();
txtbx.ID = "txtQuestion_" + productQuestionId.ToString(); //productQuestionId is the datakey value of this ListViewItem
placeholder.Controls.Add(txtbx);
当用户点击按钮时,我需要能够获得他们填写的值。
在我的研究中,我发现我需要首先重新创建动态添加的控件,以便根据页面生命周期获取它们的值。
以下是我在按钮处理程序中重新创建控件的内容:
foreach (ListViewDataItem item in lvQuestions.Items)
{
HiddenField hdField = (HiddenField)item.FindControl("hfQuestionId");
PlaceHolder plcHolder = (PlaceHolder)item.FindControl("plControl");
TextBox txtbx = new TextBox();
txtbx.ID = "txtQuestion_" + hdField.Value;
plcHolder.Controls.Add(txtbx);
}
然后在同一个处理程序中的下一个代码块我重新遍历ListViewDataItems并找到控件:
foreach (ListViewDataItem item in lvQuestions.Items)
{
HiddenField hdField = (HiddenField)item.FindControl("hfQuestionId");
PlaceHolder plcHolder = (PlaceHolder)item.FindControl("plControl");
TextBox txtbx = (TextBox)plcHolder.FindControl("txtQuestion_" + hdField.Value);
if (txtbx != null)
{
Response.Write("TextBox Found:" + txtbx.Text);
}
}
找到了文本框,但没有任何价值。这就像我刚刚在上一个块中用新的文本框写了一样。如果我删除了上一段代码,则找不到任何文本框。
有人可以帮助我解决我在这里缺少的事情吗?
谢谢。
答案 0 :(得分:3)
正如您已经发现的那样,这是一个生命周期问题。尝试在ListView.ItemCreated事件中创建动态控件,而不是ListView.ItemDataBound事件。
答案 1 :(得分:1)
我认为这里的问题是,在您尝试读取这些值之前,生命周期没有机会使用其提交的值填充控件。
通常情况下,如果我要做这样的事情,我会重新创建Page_Init事件中的控件,这些控件在将值加载到控件之前发生。您也可以在特定控件的Init事件中执行此操作,但这是需要将其他控件重新添加到页面的位置。
答案 2 :(得分:0)
这对我不起作用,所以我必须在PreInit调用中执行此操作
protected override void OnPreInit(EventArgs e)
{
base.OnPreInit(e);
foreach (ListViewDataItem item in lvQuestions.Items)
{
HiddenField hdField = (HiddenField)item.FindControl("hfQuestionId");
PlaceHolder plcHolder = (PlaceHolder)item.FindControl("plControl");
if (hdField != null && plcHolder != null)
{
TextBox txtbx = new TextBox();
txtbx.ID = "txtQuestion_" + hdField.Value;
plcHolder.Controls.Add(txtbx);
}
}
}
我将此方法移回ItemDataBound事件
protected void lvQuestions_ItemDataBound(object sender, ListViewItemEventArgs e)
{
object datakey = lvQuestions.DataKeys[e.Item.DataItemIndex].Value; //get datakey here
TextBox txtbx = new TextBox();
txtbx.EnableViewState = true;
txtbx.ID = "txtQuestion_" + datakey.ToString(); //productQuestionId is the datakey value of this ListViewItem
PlaceHolder pl = e.Item.FindControl("plControl") as PlaceHolder;
HiddenField hf = e.Item.FindControl("hfQuestionId") as HiddenField;
if (pl != null)
pl.Controls.Add(txtbx);
if (hf != null)
hf.Value = datakey.ToString();
}
然后它开始工作。