Monday, June 13, 2011

Working with dynamically added controls in ASP.NET

The two main problems that are frequently encountered when working with dynamically added controls in ASP.Net are:

1. The loss of the controls after a post back occurs

2. The loss of the control’s value after a post back occurs

A typical problem that one could encounter when using dynamically added controls could be as follows:

IDEA:

1. At run time, a list of controls is added to a table

2. There is a “Submit” button to submit the information at the bottom of the page

3. Validation is performed on all of the controls on the page on click of the button, if the validation fails, the user is prompted to update the values

protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
//First, add a new row to the table.
TableRow newRow = new TableRow();
//Create the LabelCell
TableCell labelCell = new TableCell();
//Create the control cell
TableCell controlCell = new TableCell();

Label nameLabel
= new Label();
nameLabel.Text
= "Name:";
labelCell.Controls.Add(nameLabel);
TextBox tb
= new TextBox();
tb.ID
= Guid.NewGuid().ToString();
controlCell.Controls.Add(tb);
newRow.Cells.Add(labelCell);
newRow.Cells.Add(controlCell);
tblCustomFields.Rows.Add(newRow);


newRow
= new TableRow();
labelCell
= new TableCell();
controlCell
= new TableCell();

nameLabel
= new Label();
nameLabel.Text
= "Surname:";
labelCell.Controls.Add(nameLabel);
tb
= new TextBox();
tb.ID
= Guid.NewGuid().ToString();
controlCell.Controls.Add(tb);
newRow.Cells.Add(labelCell);
newRow.Cells.Add(controlCell);
tblCustomFields.Rows.Add(newRow);

newRow
= new TableRow();
labelCell
= new TableCell();
controlCell
= new TableCell();

nameLabel
= new Label();
nameLabel.Text
= "Submit";
labelCell.Controls.Add(nameLabel);
Button submitButton
= new Button();
submitButton.Click
+= submitButton_Click;
submitButton.Text
= "SUBMIT";
controlCell.Controls.Add(submitButton);
newRow.Cells.Add(labelCell);
newRow.Cells.Add(controlCell);
tblCustomFields.Rows.Add(newRow);
}
}
PROBLEM:

When the user clicks the “Submit” button, a postback occurs. This causes all the controls that have been added to the page to disappear

REASON:

The reason for this problem is that because the controls are not part of the page’s markup, the framework is not aware that it should be redrawing the controls. In order for the controls to be visible on every postback, they must be redrawn on every postback of the page. The controls can be added in the Page_Init method or at the latest, within the Page_Load method.


To stop the controls from disappearing, remove the if(!IsPostBack) check and perform this logic on every postback:


 


 protected void Page_Load(object sender, EventArgs e)
{
//First, add a new row to the table.
TableRow newRow = new TableRow();
//Create the LabelCell
TableCell labelCell = new TableCell();
//Create the control cell
TableCell controlCell = new TableCell();

Label nameLabel
= new Label();
nameLabel.Text
= "Name:";
labelCell.Controls.Add(nameLabel);
TextBox tb
= new TextBox();
tb.ID
= Guid.NewGuid().ToString();
controlCell.Controls.Add(tb);
newRow.Cells.Add(labelCell);
newRow.Cells.Add(controlCell);
tblCustomFields.Rows.Add(newRow);


newRow
= new TableRow();
labelCell
= new TableCell();
controlCell
= new TableCell();

nameLabel
= new Label();
nameLabel.Text
= "Surname:";
labelCell.Controls.Add(nameLabel);
tb
= new TextBox();
tb.ID
= Guid.NewGuid().ToString();
controlCell.Controls.Add(tb);
newRow.Cells.Add(labelCell);
newRow.Cells.Add(controlCell);
tblCustomFields.Rows.Add(newRow);

newRow
= new TableRow();
labelCell
= new TableCell();
controlCell
= new TableCell();

nameLabel
= new Label();
nameLabel.Text
= "Submit";
labelCell.Controls.Add(nameLabel);
Button submitButton
= new Button();
submitButton.Click
+= submitButton_Click;
submitButton.Text
= "SUBMIT";
controlCell.Controls.Add(submitButton);
newRow.Cells.Add(labelCell);
newRow.Cells.Add(controlCell);
tblCustomFields.Rows.Add(newRow);

}

But the control’s values are lost!


As you can see in the example above, I have deliberately set the ID’s of the text box controls to a random Guid on declaration. This is to illustrate that if you do not maintain the same ID for the controls on a postback, the values of the controls that were set before the postback get cleared after they are redrawn. The behaviour in the example above is that on clicking the “Submit” button, even though the controls don’t disappear as they originally did, the values entered in the textboxes are blank after post back.


The solution here is to always ensure that:


1. You must always give your controls an ID


2. This ID must be persisted across postback


The next article will discuss using the ViewState to persist the values in the controls when a postback caused by an external control causes the values in the form to clear. Watch this space.


Technorati Tags: ,,