Geeks With Blogs
The Quandary Phase This code was generated by a tool.

This is part 1 of what I intend to be something of a recurring theme: how to avoid the use of dynamic controls in ASP.NET.

Whilst dynamic controls have their uses in a small number of cases, they come with a significant amount of extra baggage. For example:

    * Dynamic controls need to be created early in the page lifecycle to participate in viewstate
    * Dynamic controls need to be re-created on each postback, and assigned the same control IDs to maintain viewstate
    * Extracting values from dynamic controls on postback is not straightforward.

There are of course workarounds to all of the above obstacles- but the fact remains, if a built-in ASP.NET control does, or can be coerced into doing, what you need, then the simpler approach should prevail.

I'm often surprised by the number of times I see some code like this:

private void CreateTextBoxes(int count)
{
TextBox tb = null;
for (int i = 0; i < count; i++)
{
tb = new TextBox();
tb.ID = "txt" + i.ToString();
this.Panel1.Controls.Add(tb);
}
}
 

To dynamically create textboxes. When asked why they are using dynamic controls, the coder will often reply 'because I don't know how many textboxes I need until runtime'. This is, of course, a valid concern, but in this case, dynamic controls are usually not a good solution when a Repeater, DataList, or ListView control can be employed to the same effect, with much less effort.

For example, let’s take the case of a page which initially loads with a single textbox, but contains a button which allows the user to add additional textboxes at runtime. To show how much easier the solution is using built-in .NET controls, I started by adding a ListView control to the page, and edited its ItemTemplate and LayoutTemplate like so:

<asp:ListView ID="lvDynamicTextboxes" runat="server" 
ItemPlaceholderID="itemPlaceholder"> <LayoutTemplate> <table> <asp:PlaceHolder ID="itemPlaceholder"
runat="server"></asp:PlaceHolder> </table> </LayoutTemplate> <ItemTemplate> <tr> <asp:TextBox ID="txtText" runat="server"> </asp:TextBox> </tr> </ItemTemplate>
</asp:ListView>

Next up, I added a button to the page, which will be used to add new textboxes:

<asp:Button ID="btnAddTextBox" runat="server" 
Text="Add" onclick="btnAddTextBox_Click" />

I then created two methods- one for binding the ListView, and one for incrementing the current textbox count, which I chose to store using ViewState:

private void BindListView()
{
//get the current textbox count int count = 1;
if (ViewState["textboxCount"] != null)
count = (int)ViewState["textboxCount"];

//create an enumerable range based on the current count IEnumerable<int> enumerable = Enumerable.Range(1, count);

//bind the listview this.lvDynamicTextboxes.DataSource = enumerable;
this.lvDynamicTextboxes.DataBind();
}

private void IncrementTextboxCount()
{
int count = 1;
if (ViewState["textboxCount"] != null)
count = (int)ViewState["textboxCount"];

count++;
ViewState["textboxCount"] = count;
}

You will notice in the above that I’m using the Enumerable.Range() method which is located within the System.Linq namespace in the .NET framework 3.0 and greater. This is used to automatically create an integer collection with a specified range: a quick and easy way of generating a datasource for these purposes.

The only thing left to do now, is bind the ListView in the page load, and increment the TextBox count and rebind when the button is clicked:

protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
this.BindListView();
}
}

protected void btnAddTextBox_Click(object sender, EventArgs e)
{
this.IncrementTextboxCount();
this.BindListView();
}

“But… hang on a minute”, you might well say, “that’s actually more code than I needed before, using dynamic controls".

Well, yes, it is. But the real gains come when you need to extract the values from the textboxes you have dynamically created. Using dynamic controls, this gets very ugly very quickly. Using a ListView, you need only to iterate through the ListView’s data items, and extract the textbox values from the data rows, like so:

private IList<string> GetValues()
{
List<string> values = new List<string>();
TextBox txt = null;
foreach (ListViewItem item in this.lvDynamicTextboxes.Items)
{
if (item is ListViewDataItem)
{
txt = (TextBox)item.FindControl("txtText");
values.Add(txt.Text);
}
}
return values;
}

And that’s all there is to it.

For preserving the values of the textboxes between postbacks, see part 2.

Posted on Sunday, October 19, 2008 5:59 PM | Back to top


Comments on this post: ASP.NET: Alternatives to Dynamic Controls - Part 1

# re: ASP.NET: Alternatives to Dynamic Controls - Part 1
Requesting Gravatar...
Thank you, Adam.

This is much more logical than needing to recreate the controls on every postback.

I'd like to be able to remove the textboxes, but am not "seeing" the way to do that. I'm using CheckBoxes instead of a button to create and add TextBoxes, and would like to figure out how to remove them when I change my mind and unselect a CheckBox.

Any suggestions would be appreciated.

- Tinker
Left by Tinker on Sep 11, 2009 3:33 AM

# re: ASP.NET: Alternatives to Dynamic linkbutton
Requesting Gravatar...
i want to add dynamic linkbutton on ButtonClick event.
and when clicking on link button it fires its event. linkbutton cannot disappear.How to do this.Please tell me.
Left by Rupesh Rasal on Feb 05, 2010 6:45 PM

# re: ASP.NET: Alternatives to Dynamic Controls - Part 1
Requesting Gravatar...
@Rupesh: please see part 2 of the article above for how to do this:

http://geekswithblogs.net/QuandaryPhase/archive/2008/10/23/asp.net-alternatives-to-dynamic-controls---part-2.aspx
Left by adampooler on Feb 05, 2010 10:21 PM

# re: ASP.NET: Alternatives to Dynamic Controls - Part 1
Requesting Gravatar...
Your example is very helpful.
I'm also wondering if you have an example that builds a listview based on perfernces from another page (that picks which columns to include on the listview)? I'm not sure how to dynamically build the headers.
Left by Frankie on May 08, 2010 7:50 AM

# re: ASP.NET: Alternatives to Dynamic Controls - Part 1
Requesting Gravatar...
good sharing
Left by ugg nightfall on Nov 17, 2010 6:42 PM

# re: ASP.NET: Alternatives to Dynamic Controls - Part 1
Requesting Gravatar...
It was very well authored and easy to understand. Unlike additional blogs I have read which are really not good. I also found your posts very interesting. In fact after reading, I had to go show it to my friend and he enjoyed it as well!
Indonesian Teak Garden Furniture | Indonesian Furniture |
Left by Deddy Agoes on Dec 07, 2010 5:29 AM

# re: ASP.NET: Alternatives to Dynamic Controls - Part 1
Requesting Gravatar...
Marvelous, this content is very much helpful and appreciating . . . . information is efficient and targeting towards complete solution to the problem.
Left by Virtual Dedicated Hosting on Mar 02, 2011 12:35 AM

Comments have been closed on this topic.
Copyright © Adam Pooler | Powered by: GeeksWithBlogs.net