Reputation: 7359
am creating some TextBoxes by backend on a text change event, Like this :
protected void txtHowMany_TextChanged(object sender, EventArgs e)
{
int totalSections = Convert.ToInt32(txtHowMany.Text.Trim());
for (int i = 1; i <= totalSections; i++)
{
TextBox tbx = new TextBox();
tbx.Text = "";
tbx.ID = "section" + i;
tbx.Style.Add("width", "90%");
tdSectionsAdd.Controls.Add(tbx);
}
trSectionsName.Visible = true;
}
The auto post back is true for txtHowMany, so when I enter a number, it generates the textboxes and add it to table division
Now the problem is, I am trying to get text from generated textboxes like this :
protected void btnSave_click(object sender, EventArgs e)
{
int numbersOfSectionsToSave = 1;
int sectionsToSave =Convert.ToInt32(txtHowMany.Text.Trim());
for (int i = 1; i < sectionsToSave; i++)
{
Sections section = new Sections();
section.CourseId = result;
section.OrganizationId = course.OrganizationId;
foreach (Control c in tdSectionsAdd.Controls)
{
if (c.GetType() == typeof(TextBox))
{
TextBox txtBox = (TextBox)c;
string id = "section" + i;
if (txtBox.ID == id)
{
section.Name = txtBox.Text.Trim();
}
}
}
string name = Request.Form["section1"];
section.CreatedBy = "Admin";
section.CreationDate = DateTime.Now;
section.ModifiedBy = "Admin";
section.ModificationDate = DateTime.Now;
numbersOfSectionsToSave += section.SaveSection();
}
But its showing 0 count for the controls in tdSectionsAdd , The controls are added before I am trying to access them, but still it shows no controls in td. Please help, How can I get these textboxes?
Thanks!
Upvotes: 2
Views: 840
Reputation: 17405
Dynamic Created controls "Disappear" on postback, if they are not "recreated" in the Page_Init of that page.
Only if they are created in the page_init will the page's viewstate get updated with their information.
Long Explantion:
When we perform a postback (or partial postback) we want to be able to access those controls (or at least the values the user put into them).
We know that the data is in the viewstate, but ASP.NET doesn’t really know which control a ViewState item belongs to. It only knows to match a viewstate item and a control through the same index (e.g. Matches item n in the viewstate tree to item n in the control tree). Therefore in order to get the dynamic controls' data, we need to re-create the controls each time the page is postbacked.
BUT in order for this to work, we need to re-create the controls in the Page_Init function NOT in the Page_Load.
Why? Because when the ViewState is created it needs all the controls to already exist.
This is taken from MSDN, as you can see the viewstate is loaded AFTER the init but before the page load.
TL;DR Call the function that creates the dynamic controls in the page_init and you should be able to see all the values the user entered when the page postbacks
A few links on this issue:
http://forums.asp.net/t/1186195.aspx/1
ASP.NET - Dynamic controls created in Page_Pre_init() or Page_Init() or Page_Load()
Option 2:
I should note: If the controls all had unique Ids and you're not interested in re-creating them again every postback - you could always look for them in the Request Object. The Request.Form is a NameValueCollection that holds the values of all the controls that were part of the form, just search it for whatever you're looking for
Upvotes: 1
Reputation: 13296
You need to add them in each postback. Store the totalSections
variable in ViewState so you can add them i page load also:
protected void AddTextBoxes()
{
int totalSections;
if (int.TryParse(Convert.ToString(ViewState["TotalSections"]), out totalSections)
{
for (int i = 1; i <= totalSections; i++)
{
TextBox tbx = new TextBox();
tbx.Text = "";
tbx.ID = "section" + i;
tbx.Style.Add("width", "90%");
tdSectionsAdd.Controls.Add(tbx);
}
trSectionsName.Visible = true;
}
}
protected void txtHowMany_TextChanged(object sender, EventArgs e)
{
ViewState["TotalSections"] = Convert.ToInt32(txtHowMany.Text.Trim());
tdSectionsAdd.Controls.Clear();
AddTextBoxes();
}
protected void Page_Load(object sender, EventArgs e)
{
AddTextBoxes();
}
Upvotes: 2