无法在中继器中找到动态添加的控件的选定值
我正在创建一个调查页面,其中包含问题和答案列表,可以是单选按钮列表、复选框列表或文本框。使用 Controls.Add 将这些控件动态添加到其 ItemDataBound 事件中的 Repeater 中。
我已经成功地渲染了页面,但是当我提交表单并迭代转发器中的控件以获取单选按钮和文本框值的选定值时,FindControl 返回 null。我需要做什么才能获得选定的值?我尝试迭代 RepeaterItems 但也返回 null。我尝试过不同类型的 FindControl 但它从未解析控件类型。 如果我像这样在中继器中添加声明性 DataBinder,它就可以工作
<asp:Repeater ID="rptSurvey" runat="server" Visible="true" EnableViewState="true" >
<ItemTemplate>
<%# DataBinder.Eval(Container.DataItem, "Question") %>
</ItemTemplate>
</asp:Repeater>
但是,我想动态添加控件,但这样做时我无法在提交时获取所选值。这是我的代码的主要结构......
<html>
<asp:Repeater ID="rptSurvey" runat="server" Visible="true">
</asp:Repeater>
<asp:Button ID="btnSubmit" runat="server" Text="Submit" OnClick="btnSubmit_Click" />
</html>
protected void Page_Load(object sender, EventArgs e)
{
...
if (!IsPostBack)
{
rptSurvey.DataSource = GetQuestions();
rptSurvey.DataBind();
}
...
}
protected void rptSurvey_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
string question = (DataBinder.Eval(e.Item.DataItem, "Question")).ToString();
litQuestion = new Literal();
litQuestion.Text = question;
RadioButtonList rblAnswer = (RadioButtonList)item;
rptSurvey.Controls.Add(rblAnswer);
}
}
protected void btnSubmit_Click(object sender, EventArgs e)
{
...
Dictionary<int, string> answers = new Dictionary<int, string>();
try
{
var list = FindControls(rptSurvey, c => c is RadioButtonList || c is CheckBoxList || c is TextBox);
foreach (Control item in list)
{
QuestionId = int.Parse(Questions.Rows[list.IndexOf(item)][0].ToString());
if (item is TextBox)
{
TextBox txtAnswer = (TextBox)item;
answers.Add(QuestionId, txtAnswer.Text);
}
else if (item is RadioButtonList)
{
RadioButtonList rblAnswer = (RadioButtonList)item;
answers.Add(QuestionId, rblAnswer.SelectedItem.Text);
}
else if (item is CheckBoxList)
{
// Iterate through the Items collection of the CheckBoxList
string cblMultiAnswer = "";
for (int i = 0; i < cblAnswer.Items.Count; i++)
{
if (cblAnswer.Items[i].Selected)
{
cblMultiAnswer += cblAnswer.Items[i].Value + ",";
}
}
answers.Add(QuestionId, cblMultiAnswer);
}
}
bSurvey.BLInsertSurveyAnswers(answers, dateCreated, _userEmail);
}
}
public static List<Control> FindControls(Control parent, Predicate<Control> match)
{
var list = new List<Control>();
foreach (Control ctl in parent.Controls)
{
if (match(ctl))
list.Add(ctl);
list.AddRange(FindControls(ctl, match));
}
return list;
}
I am creating a survey page that has a list of questions and answers that can be radiobuttonlists, checkboxlists or textboxes. These controls are added dynamically to a Repeater in its ItemDataBound event using Controls.Add.
I've managed to render the page ok but when I submit the form and iterate over the controls in the repeater to get the selectedvalues of the radiobuttons and textbox values, FindControl returns null. What do I need to do to get get the selected values? I've tried iterating over the RepeaterItems but that returned null too. I've tried different types of FindControl but it never resolves the control types.
It works if I add a declarative DataBinder in the Repeater like this
<asp:Repeater ID="rptSurvey" runat="server" Visible="true" EnableViewState="true" >
<ItemTemplate>
<%# DataBinder.Eval(Container.DataItem, "Question") %>
</ItemTemplate>
</asp:Repeater>
However, I want want to dynamically add the controls but in doing this i cant get the selectedvalues when submitting. This is tha main structure of my code...
<html>
<asp:Repeater ID="rptSurvey" runat="server" Visible="true">
</asp:Repeater>
<asp:Button ID="btnSubmit" runat="server" Text="Submit" OnClick="btnSubmit_Click" />
</html>
protected void Page_Load(object sender, EventArgs e)
{
...
if (!IsPostBack)
{
rptSurvey.DataSource = GetQuestions();
rptSurvey.DataBind();
}
...
}
protected void rptSurvey_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
string question = (DataBinder.Eval(e.Item.DataItem, "Question")).ToString();
litQuestion = new Literal();
litQuestion.Text = question;
RadioButtonList rblAnswer = (RadioButtonList)item;
rptSurvey.Controls.Add(rblAnswer);
}
}
protected void btnSubmit_Click(object sender, EventArgs e)
{
...
Dictionary<int, string> answers = new Dictionary<int, string>();
try
{
var list = FindControls(rptSurvey, c => c is RadioButtonList || c is CheckBoxList || c is TextBox);
foreach (Control item in list)
{
QuestionId = int.Parse(Questions.Rows[list.IndexOf(item)][0].ToString());
if (item is TextBox)
{
TextBox txtAnswer = (TextBox)item;
answers.Add(QuestionId, txtAnswer.Text);
}
else if (item is RadioButtonList)
{
RadioButtonList rblAnswer = (RadioButtonList)item;
answers.Add(QuestionId, rblAnswer.SelectedItem.Text);
}
else if (item is CheckBoxList)
{
// Iterate through the Items collection of the CheckBoxList
string cblMultiAnswer = "";
for (int i = 0; i < cblAnswer.Items.Count; i++)
{
if (cblAnswer.Items[i].Selected)
{
cblMultiAnswer += cblAnswer.Items[i].Value + ",";
}
}
answers.Add(QuestionId, cblMultiAnswer);
}
}
bSurvey.BLInsertSurveyAnswers(answers, dateCreated, _userEmail);
}
}
public static List<Control> FindControls(Control parent, Predicate<Control> match)
{
var list = new List<Control>();
foreach (Control ctl in parent.Controls)
{
if (match(ctl))
list.Add(ctl);
list.AddRange(FindControls(ctl, match));
}
return list;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您必须首先创建控制树(始终 - 不仅在非回发时)。在 oninit 或 onpreload 事件中执行此操作。
看这里: https:// web.archive.org/web/20211020131055/https://www.4guysfromrolla.com/articles/081402-1.aspx
you have to create the control tree first (always - not only on non-postbacks). do it in the oninit or onpreload event.
look here: https://web.archive.org/web/20211020131055/https://www.4guysfromrolla.com/articles/081402-1.aspx