Search code examples
asp.netcontrolsrepeaterradiobuttonlistfindcontrol

Cannot find selected value of dynamically added controls in repeater


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

Solution

  • 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