Add Controls Dynamically - Part 3
Posted by gabriel,
Mon Jul 21 21:55:00 UTC 2008
On the last article of this series we saw how we could assign event handlers to dynamically created controls and how the PlaceHolder control could help us add the controls in a more organized way.
Related posts:- Add Controls Dynamically – Part 1
- Add Controls Dynamically – Part 2
- Add Controls Dynamically – Part 3
- Add Controls Dynamically – Part 4
- Add Controls Dynamically – Part 5
In this article I want to show how you can keep a reference of a dynamically created control so that you can use it later somewhere else in your code. For this I’ll continue using the code created add the end of the last article of this series.
Now that you can add as many TextBoxes to the form as you want let’s say that you want to use them to input numeric values and then add up all the values for display. The first thing then is to decide where do we want to keep the reference to the controls. I chose to use a generic list of TextBox (List
System.Collections.Generic.List<TextBox> controlsList = new System.Collections.Generic.List<TextBox>();
Now that the list is declared and created the next step is deciding when we are going to add the controls to the list. To me using the method that adds the controls dynamically feels like the best choice, maybe someone has another idea (please share if you do). So the method would look like this:
private void createDynamicControls()
{
TextBox tb = new TextBox();
tb.TextChanged += TextBox_TextChanged;
PlaceHolder1.Controls.Add(tb);
controlsList.Add(tb);
}
Easy, right? Ok, the last step now is adding a button to the form that will call the logic to add the values within all the controls and add a label that will display the result of the addition. The logic for adding the values is very simple, once you have a list with all the controls you only need to iterate through the list, get the value of the control and add it to a variable. Here is the code:
protected void ButtonAdd_Click(object sender, EventArgs e)
{
int value = 0;
foreach (TextBox tb in controlsList)
{
value += int.Parse(tb.Text);
}
LabelTotal.Text = value.ToString();
}
Please notice that I have assumed that all the TextBoxes are provided with valid numeric values. We could improve the code to check for empty values and conversion errors however this is not the main goal of this article. Here is a complete version of the page after all our changes were made:
<%@ Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
System.Collections.Generic.List<TextBox> controlsList = new System.Collections.Generic.List<TextBox>();
void Page_Load(object sender, EventArgs e)
{
//when the user first enters the page set the count as zero
if (!IsPostBack)
{
ViewState["count"] = 0;
}
//on every subsequent postback, check the control count
//and recreated all the controls
else
{
int controlCount = (int)ViewState["count"];
for (int i = 0; i < controlCount; i++)
{
createDynamicControls();
}
}
}
protected void Button1_Click(object sender, EventArgs e)
{
createDynamicControls();
//increment the number of controls
ViewState["count"] = (int)ViewState["count"] + 1;
}
//this method takes care of creating the controls
private void createDynamicControls()
{
TextBox tb = new TextBox();
tb.TextChanged += TextBox_TextChanged;
PlaceHolder1.Controls.Add(tb);
controlsList.Add(tb);
}
private void TextBox_TextChanged(object sender, EventArgs e)
{
//the sender is the control that fired the event
//that is the control we want to change the color
TextBox tb = (TextBox)sender;
tb.BackColor = System.Drawing.Color.Yellow ;
}
protected void ButtonAdd_Click(object sender, EventArgs e)
{
int value = 0;
foreach (TextBox tb in controlsList)
{
value += int.Parse(tb.Text);
}
LabelTotal.Text = value.ToString();
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder>
<br />
<asp:Button ID="Button1" runat="server" Text="Add TextBox"
onclick="Button1_Click" />
<br />
<asp:Button ID="ButtonAdd" runat="server" Text="Add all values"
onclick="ButtonAdd_Click" />
<br />
Total:<asp:Label ID="LabelTotal" runat="server" Text=""></asp:Label>
</div>
</form>
</body>
</html>