To add controls to an aspx page dynamically, follow these steps.
First, add a placeholder on the ASPX page:
<asp:PlaceHolder runat="server" id="AssessCanvas" />
Mine is called "AssessCanvas". Next, add the controls themselves. Here is code that I use in methods called by Page_Load to create a label and a text box. The label is a prompt for "Weight:" and the text box is used to enter a weight value (in the example, I am also including a value for weight when I create the box):
Label aLbl = new Label { Text = "Weight: ", ID = ("WSLabel" + counter) };
counter++;
AssessCanvas.Controls.Add(aLbl);
TextBox aBox = new TextBox { ID = "XTest1", Columns = 5, Text = weight.ToString("##0.0"), Width = 50 };
AssessCanvas.Controls.Add(aBox);
I use "WSLabelN" (where N is a number) to give a unique ID to each label. Because I'll want to scan all of my text boxes to pull their contents when the form is submitted, I give each of them an ID of the form "XTestN" (where N is a unique identifier for each field - here the "XTest1" tells me that this is the weight field).
When I'm ready to handle the form submit, I do this:
// Look at each key submitted with the form - *some* of these will be my input text boxes
foreach (string aStr in form.AllKeys)
{
// Is this an input text box? Yes if it has "XTest" in it somewhere.
int position = aStr.IndexOf("XTest");
if (position > 0)
{
// The data entry fields for each input box follows the format: <ASP.NET Prefix>XTest<TID>
// Here I get the tid so I know what to do with the value that was entered
short tid = BSDIUtil.StrToIntDef(aStr.Substring(position + 5));
switch (tid)
{
case 1: SaveWeight(BSDIUtil.StrToFloatDef(form.Get(aStr))); break;
case 2: SaveJP3P1(BSDIUtil.StrToFloatDef(form.Get(aStr))); break;
... etc...
}
}
}
In my system, I often have to place several fields on the page to collect values for one testing item (the system here comes from a fitness testing page). For example, "SaveJP3P1" above isn't called as shown because it actually pulls data from nine different fields. I simplified it for the example for obvious reasons.
This approach gives you a great deal of flexibility. In my full page, I have check-boxes, header labels (e.g. a label with HTML/CSS formatting in addition to the label text), and even several DIVS for fitness tests with multiple panels for their input. And all of it is done dynamically. Obviously, a grid wouldn't work and neither would just adding a control to the control tree as others have suggested.