Dynamic Controls in ASP.NET

http://aspnet.4guysfromrolla.com/articles/081402-1.aspx 

 

For More Information on Working with Dynamically Created Controls...
After you have read this article, consider reading the following articles for a more in-depth look at working with dynamically created controls in an ASP.NET Web page:
  • Working with Dynamically Created Controls
    Looks at how to find a particular dynamically created control, and how to set/read its properties. Also examines how to iterate through all dynamically created controls on a page.
  • Dynamic Web Controls, Postbacks, and View State
    Examines using dynamic Web controls that can fully participate in the standard page lifecycle. Shows when to add controls programmatically so that their view state and values are persisted correctly across postback.

Introduction
If you're reading this article, you've no doubt created an ASP.NET Web page with various Web controls. Typically one creates Web controls statically, by explicitly specifying them in the HTML section of an ASP.NET Web page. For example, one might create an ASP.NET Web page that contains an HTML message and a TextBox, which would contain the following code:

What is your name?
<asp:textbox runat="server" id="txtName" />

The code above specifies two Web controls:

  1. A LiteralControl (the "What is your name" HTML gets converted into a LiteralControl when the ASP.NET Web page is requested from a browser for the first time), and
  2. A TextBox Web control

The above code explicitly specifies the controls that should appear on the ASP.NET Web page (granted, the HTML being converted into a LiteralControl is a bit implicit). Did you know that you can dynamically add controls to an ASP.NET Web page? In this article we'll look at how to create controls, add them to an ASP.NET page dynamically, and, finally, how to enumerate through the controls on a page.

The Page Class
When an ASP.NET Web page is first visited by a user it is converted into a class that inherits the Page class. If you use code-behind you're already aware of this - your code-behind class has to explicitly inherit the Page class. By inheriting the Page class, the ASP.NET Web page has access to the various useful properties, methods, and events of the Page class.

For example, the Page_Load event handler is triggered when the Page class's Load event is fired. Similarly, you've no doubt used a number of the Page class's properties, such as IsPostBack, IsValid, Request, Response, Session, Cache, etc.

The Page class is derived (indirectly) from the Controls class, which has a property called Controls, which is a collection representing the controls contained by the Page class, which is simply the controls on the ASP.NET Web page. Hence, to add controls to an ASP.NET Web page we will add them to this collection.

If the above three paragraphs have utterly confused you, don't worry! A couple examples should help clear things up.

Adding a Dynamic Control to an ASP.NET Web Page
In order to add a control to an ASP.NET Web page we first need to create an instance of the control we wish to add. For our example, we'll add a Label control to the Web page. Hence, we first need to create the Label control, which we can do in our Page_Load event handler like so:

<script runat="server" language="VB">
    sub Page_Load(sender as Object, e as EventArgs)
      Dim lblMessage as New Label()

      ...

Pretty simple, eh? Next, we need to set the various Label properties we're interested in. For this example, let's set the Text and the Font.Bold property:

      lblMessage.Text = "Hello, World!"
      lblMessage.Font.Bold = True

Finally, we need to add this control to the Web page. Not surprisingly, the Controls property has an Add method, which is demonstrated in the following code:

      Controls.Add(lblMessage)
    end sub
</script>
[ View a Live Demo!]

Take a moment to check out the live demo. Note that the control is added to the end of the Web page. This is because by the time the Page_Load handler has fired the other controls on the page (the LiteralControl that comprises the HTML markup) have already been added. The Add method adds the Label control to the end of the Controls collection.

While the Controls collection contains an AddAt method, allowing the developer to specify specifically where in the Controls collection the new control should be added, if we want the control to appear in a fixed location within the Web page (say, between the two <HR>s (horizontal lines) in the live demo), we have to somehow break up the HTML markup so that it is comprised of two LiteralControls instead of one, so we can place our Label control in the correct spot (as opposed to the very end of the HTML content or the very beginning).

To accomplish this, we need to use a PlaceHolder Web control, specifying explicitly where in the ASP.NET Web page it belongs. For example, imagine we have the following HTML in our Web page:

  Blah blah blah
  <hr>
  <hr>
  Blah blah blah

and we want to add our Label control to the Web page such that it appears between the two <HR> tags. To accomplish this, we first add a PlaceHolder control specifically where we want the Label control to appear:

  Blah blah blah
  <hr>
  <asp:PlaceHolder runat="server" id="LabelPlaceHolder" />
  <hr>
  Blah blah blah
[ View a Live Demo!]

To complete this exercise, in the Page_Load event handler we replace Controls.Add(lblMessage) with LabelPlaceHolder.Controls.Add(lblMessage). This adds the Label control to the PlaceHolder's Controls collection. The reason the PlaceHolder control has a Controls property is because it is derived from the Control class - in fact, all ASP.NET controls are. As aforementioned, the Control class has a Controls property, which is a collection of all of the children controls in the control at hand. Hence, we are adding the Label control lblMessage to the PlaceHolder control. (See the live demo for the complete source code...)

In Part 2 we'll look at how to enumerate through the controls in an ASP.NET Web page. Also, we'll look at some real-world applications for dynamically adding controls!

Dynamic Controls in ASP.NET, Part 2

In Part 1 we examined how to add controls to an ASP.NET Web page, and how to specify the precise location of the control using a PlaceHolder control. In this part we'll examine how to enumerate through the controls on a page and some real-world uses of dynamically adding controls to an ASP.NET Web page.

Enumerating through the Controls on an ASP.NET Web Page
Since the Controls property is a collection that supports the IEnumerable interface, you can simple iterate through the collection using a For Each ... Next loop in VB.NET or a foreach loop in C#. (For the remainder of this article I will be using C# code samples.) To loop through the controls in the Page, simply use the following code:

<script runat="server" language="C#">
  void Page_Load(Object sender, EventArgs e)
  {      
    foreach(Control c in Controls)
      lblControlList.Text += c.ToString() + " - " + c.ID + "<br>";
  }
</script>

<html>
<head>
</head>
<body>
    <b>A List of the Controls in the 
    <code>Controls</code> Collection</b><br>
    <asp:label runat="server" id="lblControlList" />
    <p>
    <form runat="server">
        What's your name?
        <asp:textbox runat="Server" id="txtName" />
    </form>
</body>
</html>
[ View a Live Demo!]

Take a moment to view the live demo. You'll note that the controls listed to be in the page are:

  • LiteralControl
  • Label
  • LiteralControl
  • HtmlForm
  • ResourceBasedLiteralControl

You may be wondering where the TextBox control is, and why it isn't listed on the live demo. This is because the TextBox is a child control of the Web Form control (the HtmlForm control). In order to view all of the controls on the Web page, we must iterate through the Controls collection, and at each control, check to see if the control has any children controls; if it does, we need to iterate recursively through its children controls, applying the same logic. (In order to determine if a control has children controls, we can simply check to see if the control's Controls collection's Count property is greater than 0.)

What is the ResourceBasedLiteralControl?
I found myself wondering this very thing when I first viewed the live demo. There's no mention of a ResourceBasedLiteralControl in the docs and a search on Google revealed nothing helpful. I turned to the ASP.NET Forums and got an answer from DmitryR, an ASP.NET Team member. DmitryR said:

[The choice of using a ResourceBasedLiteralControl vs. a LieralControl is] based on size, it is a perf optimization -- static HTML of size over 1K(?) ends up as a utf-8 encoded resource, saving the conversion cost and string size.

The following code example illustrates how to recursively iterate through all of the controls on the page. It utilizes recursion - if you are unfamiliar or rusty with recursion, I'd recommend that you read Recursion - Why It's Cool first.

<script runat="server" language="C#">
    void IterateThroughChildren(Control parent)
    {
      foreach (Control c in parent.Controls)
      {
        lblControlList.Text += "<li>" + c.ToString() + "</li>";
        if (c.Controls.Count > 0)
        {
          lblControlList.Text += "<ul>";
          IterateThroughChildren(c);
          lblControlList.Text += "</ul>";
        }
      }
    }

    void Page_Load(Object sender, EventArgs e)
    {      
      lblControlList.Text += "<ul>";
      IterateThroughChildren(this);
      lblControlList.Text += "</ul>";
    }
</script>

<html>
<head>
</head>
<body>
    <b>A List of the Controls in the 
    <code>Controls</code> Collection</b><br>
    <asp:label runat="server" id="lblControlList" />
    <p>
    <form runat="server">
        What's your name?
        <asp:textbox runat="Server" id="txtName" />
    </form>
</body>
</html>
[ View a Live Demo!]

Ok, this is Neat, but is it Useful?
Hopefully you've found the material that we've covered thus far to be interesting, if nothing else. But, if you're like me, when you first hear about this topic you may find yourself thinking, "Well, yeah, this is neat and all, but when in the world would I use it?" Personally I have yet to use it in a real-world application, but can envision a number of potential uses.

Imagine that you want to have surveys or questionnaires on your Web site. Ideally each survey would have a database record, and a set of rows indicating what the questions were and what types of questions they were. For example, you might have a survey that had three questions: one a Yes/No, one a write-in, and one being a selection from five potential options. (In this case you'd need a couple of DropDownLists and a TextBox.) In any event, rather than have to create a new ASP.NET Web page for each potential survey, you could create one generic page that accepts a survey ID through the querystring, and then dynamically adds the appropriate questions and controls accompanying the questions. See? A useful, real-world application of the material we just covered! ;-)

Conclusion
In this article we examined how to dynamically add controls to an ASP.NET Web page. Furthermore, we looked at how to iterate through the Controls collection as well as how to recursively iterate through the entire set of controls on a page. For more information on working with dynamically added controls, be sure to read: Working with Dynamically Created Controls.

Happy Programming!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值