ASP.Net – Dynamically adding controls and persisting state

Posted by: | Technical | 04.01.2009

The following example provides a basic solution for creating web controls on the fly. This is based on the scenario where a user can add/remove additional textboxs and link buttons to an asp.net web form by clicking a button.

Dynamic controls must be created at Page_Init or Page_Load in the page’s life cycle, in order to persist the state of each webcontrol after postbacks to the server. In the code below, i simply create ASP.NET controls dynamically after the On_Click event of lbtnAdd fires. Alternatively, i could create a usercontrol template, an ascx file that already contains the webcontrols that need to be created, and dynamically add it to the page when the user requests it.

See below for the codebehind snippet… followed by the aspx page. Or, download the Sample Website here

Helpful link – http://www.codeproject.com/KB/user-controls/DynamicUC.aspx

//codeBehind.cs file

private Int16 _ctrlCount = -1;

public Int16 CtrlCount

{

get

{

if (Int16.TryParse(hdnCtrlCount.Value, out _ctrlCount))

return _ctrlCount;

else

return 0;

}

set

{

hdnCtrlCount.Value = value.ToString();

}

}

protected void Page_Load(object sender, EventArgs e)

{

if (Page.IsPostBack)

AddUserControls();

}

protected void lbtnAdd_OnClick(object sender, EventArgs e)

{

// handle this in page_load

}

protected void lbtnRemove_Click(object sender, EventArgs e)

{

LinkButton lbtn = (LinkButton)sender;

if (lbtn != null)

{

// Keep track of the deleted controls’ IDs

// so that deleted data is not persisted.

hdnDeletedControlIDs.Value = hdnDeletedControlIDs.Value + “|” + lbtn.CommandArgument;

pnlControls.Controls.Remove(lbtn.Parent);

}

}

protected void btnSubmit_OnClick(object sender, EventArgs e)

{

// test to check that data is being persisted between postbacks

ltlResult.Text = string.Empty;

TextBox txt;

foreach (Control parentCtrl in pnlControls.Controls)

{

if (parentCtrl is Panel)

{

foreach (Control ctrl in parentCtrl.Controls)

{

if (ctrl is TextBox)

{

txt = (TextBox)ctrl;

ltlResult.Text = ltlResult.Text + txt.Text + “<br />”;

}

}

}

}

}

private void AddUserControls()

{

pnlControls.Controls.Clear();

// Get the button that posted back, if it exists.

string ctrID = string.Empty;

if (Page.Request.Params["__EVENTTARGET"] != null)

ctrID = Page.Request.Params["__EVENTTARGET"].ToString();

if (ctrID.Equals(”lbtnAdd”))

CtrlCount++;

for (int i = 1; i <= CtrlCount; i++)

{

string textboxID = “txt” + i.ToString();

if (!InDeletedList(textboxID))

{

// first create a panel control to hold the

// new block of dynamically created controls

Panel pnlParent = new Panel();

TextBox txt = new TextBox();

txt.ID = textboxID;

txt.CssClass = “textbox”;

LinkButton lbtn = new LinkButton();

lbtn.ID = “lbtnDelete” + i.ToString();

lbtn.Text = “Delete”;

lbtn.CommandArgument = txt.ID;

lbtn.Click += new EventHandler(lbtnRemove_Click);

Literal ltl = new Literal();

ltl.Text = “<br />”;

pnlParent.Controls.Add(txt);

pnlParent.Controls.Add(lbtn);

pnlParent.Controls.Add(ltl);

pnlControls.Controls.Add(pnlParent);

}

}

}

private bool InDeletedList(string id)

{

// Check to see whether the control has previously been deleted

// Adding a control that was deleted will inadvertently persist the deleted

// controls data.

string[] DeletedIDs = hdnDeletedControlIDs.Value.Split(’|’);

if (DeletedIDs.Length > 0)

{

foreach (string deletedID in DeletedIDs)

{

if (deletedID.Equals(id))

return

true;

}

}

return false;

}

// .aspx page

<asp:ScriptManager ID=”scriptmanager1? runat=”server”></asp:ScriptManager>

<div>

<asp:UpdatePanel ID=”upControlColection” runat=”server”>

<ContentTemplate>

<asp:HiddenField ID=”hdnDeletedControlIDs” runat=”server” />

<asp:HiddenField ID=”hdnCtrlCount” runat=”server”/>

<asp:Panel ID=”pnlControls” runat=”server”></asp:Panel>

<br />

<asp:LinkButton ID=”lbtnAdd” runat=”server”

OnClick=”lbtnAdd_OnClick”

Text=”add”></asp:LinkButton>

<br />

<asp:Button ID=”btnSubmit” runat=”server”

OnClick=”btnSubmit_OnClick”

Text=”Submit”/>

<br />

<asp:Literal ID=”ltlResult” runat=”server”></asp:Literal>

</ContentTemplate>

</asp:UpdatePanel>

</div>

Leave a Reply