I'm trying to create TextBox
dynamically. But it's not working. It gives me an error:
Control '0' of type 'TextBox' must be placed inside a form tag with runat=server.
Here is my aspx code:
<asp:Content ID="Content2" ContentPlaceHolderID="body" Runat="Server">
<form id="form" runat="server">
<asp:Button ID="Button2" runat="server" OnClick="show" Text="Button" />
<asp:TextBox ID="TextBox" runat="server"></asp:TextBox>
</form>
</asp:Content>
Here is my Codebehind:
public void show(object sender, EventArgs e)
{
for (int i =0; i <3; i++)
{
TextBox _text = new TextBox();
_text.Visible = true;
_text.Text = i.ToString();
_text.ID = i.ToString();
this.Controls.Add(_text);
}
}
Try this:
this.Form.Controls.Add(_text);
The error tells you that TextBox must be inside <form>
tag. If you add it to Controls of "this", it's added after <form>
.
Even if you place controls inside form control, you won't be able to retrieve the value on postback.
The problem with dynamic control is you will need to reload the control (with same id) on every post back of the page.
Otherwise, they'll not be in the control tree, and you won't be able to find them.
Here is a sample. It loads TextBox control dynamically, and displays the value back when Submit button is clicked.
ASPX
<asp:PlaceHolder runat="server" ID="PlaceHolder1" />
<asp:Button runat="server" ID="OkButton" OnClick="OkButton_Click" Text="Ok" />
<asp:Button runat="server" ID="SubmitButton" OnClick="SubmitButton_Click" Text="Submit" />
<asp:Label runat="server" ID="MessageLabel" />
Code Behind
protected void Page_Init(object sender, EventArgs e)
{
if (IsPostBack)
{
LoadControls();
}
}
protected void OkButton_Click(object sender, EventArgs e)
{
LoadControls();
}
protected void SubmitButton_Click(object sender, EventArgs e)
{
var myTextBox = FindControlRecursive(PlaceHolder1, "MyTextBox") as TextBox;
MessageLabel.Text = myTextBox.Text;
}
private void LoadControls()
{
// Ensure that the control hasn't been added yet.
if (FindControlRecursive(PlaceHolder1, "MyTextBox") == null)
{
var myTextBox = new TextBox {ID = "MyTextBox"};
PlaceHolder1.Controls.Add(myTextBox);
}
}
public static Control FindControlRecursive(Control root, string id)
{
if (root.ID == id)
return root;
return root.Controls.Cast<Control>()
.Select(c => FindControlRecursive(c, id))
.FirstOrDefault(c => c != null);
}
Add controls to the form
instead of adding them to this
for (int i =0; i <3; i++)
{
TextBox _text = new TextBox();
_text.Visible = true;
_text.Text = i.ToString();
_text.ID = i.ToString();
form.Controls.Add(_text);
}