When we add controls dynamically, main problem is accessing previous one added control value during postback. For solving this problem save all added controls at viewstate and during load viewstate event collect all added controls info and add again to the page.
We not only need to add them to the forms control collection, but we also need to build the notification mechanism to let the ASP.NET engine know that our newly added controls exist on each subsequent postback.
In the following example two textbox create dynamically on button click event. Both are added at single row. After that adding both text box add next line code. Another button for getting textbox value. Here their id write.
----------------------- Code ---------------------------------
using System.Collections.Generic;
public partial class dynamic_Default : System.Web.UI.Page
{
int controlCounter = 0;
List myControlList;
protected override void LoadViewState(object savedState)
{
base.LoadViewState(savedState);
myControlList = (List)ViewState["myControlList"];
foreach (string ctlID in myControlList)
{
controlCounter++;
TextBox box = new TextBox();
box.ID = ctlID;
controlHolder.Controls.Add(box);
if((controlCounter%2) == 0)
{
LiteralControl lineBreak = new LiteralControl("
");
controlHolder.Controls.Add(lineBreak);
}
}
}
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
myControlList = new List();
ViewState["myControlList"] = myControlList;
}
}
protected void Create_Click(object sender, EventArgs e)
{
//Response.Write(controlCounter);
controlCounter++;
TextBox box = new TextBox();
box.ID = "textBox" + controlCounter.ToString();
controlHolder.Controls.Add(box);
TextBox newTemp = new TextBox();
newTemp.ID = "txtNew" + controlCounter.ToString();
controlHolder.Controls.Add(newTemp);
LiteralControl lineBreak = new LiteralControl("
");
controlHolder.Controls.Add(lineBreak);
myControlList.Add(box.ID);
myControlList.Add(newTemp.ID);
ViewState["myControlList"] = myControlList;
}
protected void Button1_Click(object sender, EventArgs e)
{
//base.LoadViewState(savedState);
myControlList = (List)ViewState["myControlList"];
foreach (string ctlID in myControlList)
{
TextBox txtnew = new TextBox();
txtnew = (TextBox)Page.FindControl(ctlID);
if (txtnew.ID.IndexOf("txtNew") != -1)
{
Response.Write(txtnew.Text);
}
}
}
}
Suggestions are always welcome.
Thanks.
We not only need to add them to the forms control collection, but we also need to build the notification mechanism to let the ASP.NET engine know that our newly added controls exist on each subsequent postback.
1. Added a generic list of strings to store the id's of the dnamically added textboxes (if you need to add multiple different types of controls you may want to use a hashtable, store the control id as the key and the control type as the value)
2. Stored the list in the pages ViewState.
3. Added the overridden loadViewState function. This function serves the purpose of reading the forms viewstate into memory. Since we want to load our controls from viewstate before any other events occur this is the appropriate function (as it happens before the Page_Load event) I use this function to load and loop through the generic list that I stored in the viewstate. On each loop I load an instance of the control into memory and give it the appropriate id. The ASP.NET engine then maps it to the object found in the viewstate.
----------------------- Code ---------------------------------
using System.Collections.Generic;
public partial class dynamic_Default : System.Web.UI.Page
{
int controlCounter = 0;
List
protected override void LoadViewState(object savedState)
{
base.LoadViewState(savedState);
myControlList = (List
foreach (string ctlID in myControlList)
{
controlCounter++;
TextBox box = new TextBox();
box.ID = ctlID;
controlHolder.Controls.Add(box);
if((controlCounter%2) == 0)
{
LiteralControl lineBreak = new LiteralControl("
");
controlHolder.Controls.Add(lineBreak);
}
}
}
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
myControlList = new List
ViewState["myControlList"] = myControlList;
}
}
protected void Create_Click(object sender, EventArgs e)
{
//Response.Write(controlCounter);
controlCounter++;
TextBox box = new TextBox();
box.ID = "textBox" + controlCounter.ToString();
controlHolder.Controls.Add(box);
TextBox newTemp = new TextBox();
newTemp.ID = "txtNew" + controlCounter.ToString();
controlHolder.Controls.Add(newTemp);
LiteralControl lineBreak = new LiteralControl("
");
controlHolder.Controls.Add(lineBreak);
myControlList.Add(box.ID);
myControlList.Add(newTemp.ID);
ViewState["myControlList"] = myControlList;
}
protected void Button1_Click(object sender, EventArgs e)
{
//base.LoadViewState(savedState);
myControlList = (List
foreach (string ctlID in myControlList)
{
TextBox txtnew = new TextBox();
txtnew = (TextBox)Page.FindControl(ctlID);
if (txtnew.ID.IndexOf("txtNew") != -1)
{
Response.Write(txtnew.Text);
}
}
}
}