Search code examples
c#asp.netweb-controls

Dynamically create different kinds of web controls


English is not my native language; please excuse typing errors.

I am creating a survey type application, and I'm not sure how I should approach so I've been doing some trials and errors.

I have a Question class

public class Question
{
    public int QuestionID;
    public string QuestionText;
    public int InputTypeID;
    public List<WebControl> Controls;

    public Question()
    {
        //initialize fields;
    }

    internal Question(int id, string text, int inputTypeId)
    {
        //assign parameters to fields
        switch(inputTypeId)
        {
            case 1:
                //checkbox
                break;
            case 2:
                //textbox
                TextBox t = new TextBox();
                Controls = new List<WebControl>();
                Controls.Add(t);
                break;
            ...
        }
    }
}

My Question.aspx looks like this:

<asp:Repeater ID="repeater" runat="server">
    <ItemTemplate>
        //Want to display a control dynamically here
    </ItemTemplate>
</asp:Repeater>

I tried this but it obviously didn't work...

<asp:Repeater ID="repeater" runat="server">
    <ItemTemplate>
        <%# DataBinder.Eval(Container.DataItem, "Controls") %>
    </ItemTemplate>
</asp:Repeater>

and I just get this.

System.Collections.Generic.List`1[System.Web.UI.WebControls.WebControl] System.Collections.Generic.List`1

One question could have

  • one textbox
  • radiobutton list
  • checkbox list

In this case, should my Question class have List<WebControl> or just WebControl?

Also, how can I render the webcontrol inside the repeater?


Solution

  • You should do this in CodeBehind, using the Repeater ItemDataBound() event. Your question class should have a List<Control> which is the base class for WebControl and other controls, allowing the flexibility for different kinds of controls.

    Doesn't have to use Page_Load but just for example,

       void Page_Load(Object Sender, EventArgs e) 
       {
             Repeater1.ItemDataBound += repeater1_ItemDataBound;
             Repeater1.DataSource = [your List<Control> containing controls to add];
             Repeater1.DataBind();
       }
    
       void Repeater1_ItemDataBound(Object Sender, RepeaterItemEventArgs e) 
       {
    
          // Execute the following logic for Items and Alternating Items.
          if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem) 
          {
    
             var controlToAdd = (Control)e.Item.DataItem;
             ((PlaceHolder)e.Item.FindControl("PlaceHolder1")).Controls.Add(controlToAdd);
    
          }
       }    
    

    And the ItemTemplate:

       <ItemTemplate>
           <asp:PlaceHolder id="PlaceHolder1" Runat="server" />
       </ItemTemplate>