Friday, August 25, 2006 9:00 AM InfinitiesLoop

TRULY Understanding Dynamic Controls (Part 1)

Part 1: Dynamic vs. Static
Part 2: Creating Dynamic Controls
Part 3: Adding Dynamic Controls to the Control Tree
Part 4: Because you don't know to render at design time

Just like ViewState, dynamic controls seem to be fodder for much debate, and a source of many confusing issues. This article will be the first of a multi-part series to detail just about everything you could ever want to know about how Dynamic Controls fit in with the framework.

ASP.NET has been out for half a decade. Maybe this article is a little late in the making. But with all of the new technologies coming down the pipe (e.g., Atlas), I thought it would be nice to get back to the basics. After all, not all of us have been in the game since the beginning :)

Actually, this article should probably be titled "TRULY Understanding ASP.NET". Because as you will see, dynamic controls really aren't that special. In learning how they fit in with the page life cycle, and how they are similar to static controls, you will gain an understanding of how ASP.NET works in general.

I decided to write this article as a direct consequence of the article I wrote on ViewState. Over the course of a few months I received dozens upon dozens of comments on that article from developers needing help. They assumed the trouble they were having was a ViewState related issue. But 75% of the time, it was actually a dynamic control issue!

Part of the problem is that so many developers think they need to create controls dynamically when there's often much more elegant or easier solutions. There's a tendency for developers to try and do "too much" themselves, and that leads to complex problems that seem to have no good solution. It's frustrating and discouraging. I've been there myself -- but I've learned that, almost always, when I find myself in that situation it's because I'm failing to see a bigger picture or I'm failing to approach the problem in an "asp.net way". I hope this article helps those who are experiencing the same thing.

I also decided to break this article up into multiple episodes, because the ViewState article is quite long, and I think this article is going to be even longer. Maybe if I give it to you in more bite size pieces it will be easier to read, no?

PART 1


 

Dynamic vs. Static: What's the difference?

Normally you "declare" controls on a form via markup and the ubiquitous runat="server" attribute. Like this:

<%@ Page Language="C#" AutoEventWireup="true"
CodeFile="MyPage.aspx.cs" Inherits="Infinity.Examples.MyPage" %>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>TRULY Understanding Dynamic Controls</title>
</head>
<body>
    <form id="form1" runat="server">
        Your name: <asp:TextBox ID="txtName" runat="server" Text="Enter your name" />
    </form>
</body>
</html>

That TextBox is a "static" control. Static controls are declared in an xml-like syntax in ASPX or ASCX files. When ASP.NET parses that markup, it generates a class on the fly that does the dirty work for you -- one by one, the code creates the controls and adds them to the control tree. The TextBox declared above results in the following auto-generated code:

private global::System.Web.UI.WebControls.TextBox @__BuildControltxtName() {
    global::System.Web.UI.WebControls.TextBox @__ctrl;
 
    #line 11 "c:\projects\Truly\MyPage.aspx"
    @__ctrl = new global::System.Web.UI.WebControls.TextBox();
 
    #line default
    #line hidden
    this.txtName = @__ctrl;
    @__ctrl.ApplyStyleSheetSkin(this);
 
    #line 11 "c:\projects\Truly\MyPage.aspx"
    @__ctrl.ID = "txtName";
 
    #line default
    #line hidden
 
    #line 11 "c:\projects\Truly\MyPage.aspx"
    @__ctrl.Text = "Enter your name";
 
    #line default
    #line hidden
    return @__ctrl;
}

The code may look scary, but it's just a really careful way of creating a TextBox, setting the ID and Text properties, and returning it. It has to be careful because it's possible that user code define things that make change the intended purpose. The #line pragmas are so the compiler can alert you to any compile errors and still give you the correct line number in the declared markup, rather than the line number of the generated code (say thank you to the compiler next time that happens -- its a great feature).

There will be one of these "build control" methods for each control you statically declare on the page. If a control exists inside another control, then the parent control's "build control" method will add them to it's own control collection. In this example, the form control contains three child controls:

private global::System.Web.UI.HtmlControls.HtmlForm @__BuildControlform1() {
    global::System.Web.UI.HtmlControls.HtmlForm @__ctrl;
 
    #line 10 "c:\projects\Truly\MyPage.aspx"
    @__ctrl = new global::System.Web.UI.HtmlControls.HtmlForm();
 
    #line default
    #line hidden
    this.form1 = @__ctrl;
 
    #line 10 "c:\projects\Truly\MyPage.aspx"
    @__ctrl.ID = "form1";
 
    #line default
    #line hidden
    System.Web.UI.IParserAccessor @__parser = ((System.Web.UI.IParserAccessor)(@__ctrl));
 
    #line 10 "c:\projects\Truly\MyPage.aspx"
    @__parser.AddParsedSubObject(new System.Web.UI.LiteralControl("\r\n  Your name: "));
 
    #line default
    #line hidden
    global::System.Web.UI.WebControls.TextBox @__ctrl1;
 
    #line 10 "c:\projects\Truly\MyPage.aspx"
    @__ctrl1 = this.@__BuildControltxtName();
 
    #line default
    #line hidden
 
    #line 10 "c:\projects\Truly\MyPage.aspx"
    @__parser.AddParsedSubObject(@__ctrl1);
 
    #line default
    #line hidden
 
    #line 10 "c:\projects\Truly\MyPage.aspx"
    @__parser.AddParsedSubObject(new System.Web.UI.LiteralControl("\r\n    "));
 
    #line default
    #line hidden
    return @__ctrl;
}

The child controls are:

  1. LiteralControl containing the straight-up text "Your name:"
  2. The txtName TextBox
  3. Another LiteralControl containing the whitespace before the end of the form tag.

Notice to create the TextBox control, this method calls that control's "build method" that we just looked at:

global::System.Web.UI.WebControls.TextBox @__ctrl1;
#line 10 "c:\projects\Truly\MyPage.aspx"
@__ctrl1 = this.@__BuildControltxtName.@__BuildControltxtName();

And notice this strange method it calls, passing the TextBox:

@__parser.AddParsedSubObject(@__ctrl1);

Because of the fact the "object" being added is a control, all that method does is call Controls.Add(@__ctrl1), thus adding the TextBox to the control tree (I say "because of the fact it is a control", because non-controls can be added as well, but how they are handled is unique to each control type).

This isn't shown in this example, but haven't you ever wondered why you declare control variables as protected? Why not private? The class that is auto-generated inherits from your code-behind (that's why you need an "inherits" attribute in the page directive). It's up to this code to create the declared controls and assign them to the variables you declare (if it exists) so that you can easily access them. Since it is derived from your code-behind class, if the variable were private, it couldn't do that!

So that is how the framework adds declared controls into the control tree. A dynamic control in the traditional sense is one that you as the page or control developer create at some point during the page lifecycle, and add to the static control tree yourself. Something like this:

protected override void OnInit(EventArgs e) {
    TextBox txtName = new TextBox();
    txtName.ID = "txtName";
    txtName.Text = "Enter your name";
    this.form1.Controls.Add(txtName);
 
    base.OnInit(e);
}

This code is not nearly as scary looking as the auto-generated code from the page parser. However, it does the same thing!

So you see, this whole silly ASPX-markup-runat-server-thing exists solely to make it easier on you to create a control tree! That's all it's there for! If it didn't exist, you could still achieve all the same functionality by creating the controls and setting their properties yourself, just like the auto-generated code does! When I first realized this, it was a eureka moment for me. So if you don't feel the same way, either you don't understand what I'm saying, or I'm crazy when compared to you. Maybe it's a little of both :)

This really blurs the line between static and dynamic controls, as it should. What you think of as a static control, is really just a control that is being dynamically created by the framework instead of by you. But neither the control or the framework really care who creates it -- they can participate in the page lifecycle one and the same, and both the control and the page it sits on don't even know the difference.

But wait!

If you have ever dealt with dynamic controls before, you know that they really are different. It's true that your experience with them may differ from that of static controls, but it's important to understand exactly why there's a difference. The difference has to do with when the control enters the control tree. When the framework adds controls, it does it extremely early in the event sequence. The only thing that happens first is the control or page constructor. That's why in OnInit or OnPreInit, the controls already exist and are ready for use (well, master pages can 'mess' with that process, but this is still a true statement).

But when you dynamically create a control, you don't have the ability to do it as early as the framework does. And that has consequences...

Stay tuned. :)

Filed under: ,

Comments

# TRULY Understanding Dynamic Controls (Part 1)

Friday, August 25, 2006 8:47 AM by DotNetKicks.com

You've been kicked (a good thing) - Trackback from DotNetKicks.com

# re: TRULY Understanding Dynamic Controls (Part 1)

Friday, August 25, 2006 9:28 AM by AndrewSeven

I'm a regular poster on AspMessageboard and while there are various specific issues, I have found that many people's issues are due to willful ignorance. Some decide that a dynamic table is better than a repeater "just because".

Shouldn't you use CreateChildControls instead of OnInit for the sample?

# re: TRULY Understanding Dynamic Controls (Part 1)

Friday, August 25, 2006 9:43 AM by miketrash

Good starting article for the series. I really enjoyed the viewstate article too.

more more more!

# re: TRULY Understanding Dynamic Controls (Part 1)

Friday, August 25, 2006 12:29 PM by InfinitiesLoop

AndrewSeven -- ignorance perhaps, but I know exactly what you are talking about. In one of the parts (I haven't got it all planned out completely yet :P) I'm going to detail real world situations people have been in where they were doing exactly what you describe, where a repeater or other databound control would have been much better. Willful? I don't know... I'm still holding out hope that once they see the light, they will switch :)

Thanks.

# re: TRULY Understanding Dynamic Controls (Part 1)

Friday, August 25, 2006 2:08 PM by AndrewSeven

I mean "willful" in the sense that they made a concious decision to go with what worked in asp classic (or other) rather than look for a better way.

Kind of like chosing DataReaders instead of DataSets because the "feel" of readers is much closer to that of an Ado recordset.

A built in mechanism that would permit some dynamic control persistence (like what Denis Baur created http://www.denisbauer.com/ASPNETControls/DynamicControlsPlaceholder.aspx ) could be a nice addition. :D

Early on (1.0) a fair number of people expected that behavior from the asp:placeholder control. :S

# re: TRULY Understanding Dynamic Controls (Part 1)

Friday, August 25, 2006 2:20 PM by InfinitiesLoop

I've seen the Dynamic Placeholder... but I consider it evil :) Because you're forcing ViewState to remember things that don't need to be remembered. If the framework had this built in, ViewState would have to store not only the state of the controls on the page, but the page itself. Yikes. Dynamic Placeholder has its uses, but its always favorable to go the extra mile and recreate the controls every request yourself.

# re: TRULY Understanding Dynamic Controls (Part 1)

Friday, August 25, 2006 4:20 PM by Jonathan Allen

Just my luck. I'm stuck on some stupid dynamic controls issue, and I've got to wait who knows how long before I get an explaination as to what may be going wrong.

That said, I am really looking forward to the rest of this article.

# re: TRULY Understanding Dynamic Controls (Part 1)

Friday, August 25, 2006 4:55 PM by InfinitiesLoop

Jonathan -- why don't you send me the details of your issue and I'll see if I can't help? Perhaps it will be a good example that I could use in the episodes to come.

# re: TRULY Understanding Dynamic Controls (Part 1)

Tuesday, September 05, 2006 9:45 PM by Bob Vandehey

As always, excellent stuff! Keep it up.

# re: TRULY Understanding Dynamic Controls (Part 1)

Friday, September 08, 2006 4:43 PM by Dynamic controls

I want to make a checkbox that once checked automatically opens a textbox and another checkbox with the same code to do it again. Can you please help me.

# ViewState and controls, a fairy tale for all of us?

Monday, September 11, 2006 8:11 AM by bojanv

Since, ViewState is a important part of developing web pages (specially web controls), i wanted to know,

# re: TRULY Understanding Dynamic Controls (Part 1)

Monday, March 05, 2007 9:17 AM by pr.arun

Good Article to learn the state of the controls during creation in aspx page dynamically ...

# re: TRULY Understanding Dynamic Controls (Part 1)

Wednesday, May 02, 2007 5:12 AM by hello

I have a grid in usercontrol, i want to handle the selectedindexchanged of the grid in the parent page.

I add the usercontrol to a webPart dynamically and want to bind the event handling.

Gridx.gridSelectionChanged += new EventHandler(MainPage_gridxSelectionChanged);

but it didnt work.

# re: TRULY Understanding Dynamic Controls (Part 1)

Thursday, May 10, 2007 2:04 PM by InfinitiesLoop

Hello hello -- you can add the event handler from the main page, you'll just have to do a FindControl on the user control to get to the grid it contains, then hook into the handler on that.

# Viewstate loosing ASP.Net Grids?

Tuesday, May 22, 2007 6:48 PM by Sérgio Amendoeira

I ran into a strange problem today that i wanted to share with you. I had a page with a DataGrid on it,

# Code-Inside Blog &raquo; Ein paar interessante .NET Links

Tuesday, June 05, 2007 5:43 AM by Code-Inside Blog » Ein paar interessante .NET Links

Pingback from  Code-Inside Blog  &raquo; Ein paar interessante .NET Links

# Code-Inside Blog &raquo; Repeater, UpdatePanels und die Datenbindung

Pingback from  Code-Inside Blog  &raquo; Repeater, UpdatePanels und die Datenbindung

# 【转贴】真正理解动态控件

Monday, July 09, 2007 11:42 PM by 青松

讲得很深刻,推荐给大家part1:Dynamicvs.Staticweblogs.asp.net/.../TRULY-U...

# Deep Dive ASP.NET Server Controls

Friday, August 10, 2007 5:37 AM by

Vor einiger Zeit habe ich eine Webcastserie zum Thema Server Controls ( ASP. NET Server Controls – eine

# Deep Dive ASP.NET Server Controls

Friday, August 10, 2007 6:14 AM by Noticias externas

Vor einiger Zeit habe ich eine Webcastserie zum Thema Server Controls ( ASP. NET Server Controls – eine

# MSDN Blog Postings &raquo; Deep Dive ASP.NET Server Controls

Friday, August 10, 2007 8:06 AM by MSDN Blog Postings » Deep Dive ASP.NET Server Controls

Pingback from  MSDN Blog Postings  &raquo; Deep Dive ASP.NET Server Controls

# TRULY Understanding Dynamic Controls (Part 4)

Friday, August 31, 2007 7:12 PM by Infinities Loop

Part 4 of my series on Truly Understanding Dynamic Controls in ASP.NET. This part covers two of the major scenarios in which you may be loading controls or user controls dynamically, and some of the posting, viewstate, and ID related issues you have probably

# ASP.NET Dynamic controls

Sunday, September 02, 2007 6:31 AM by primoz.tech.blog

ASP.NET Dynamic controls

# TRULY Understanding Dynamic Controls (Part 4)

Tuesday, September 04, 2007 7:59 PM by Infinities Loop

Part 4 of my series on Truly Understanding Dynamic Controls in ASP.NET. This part covers two of the major scenarios in which you may be loading controls or user controls dynamically, and some of the posting, viewstate, and ID related issues you have probably

# More WebForms roadblocks and a glimpse of hope

Friday, September 07, 2007 3:10 PM by The Net: the Good, the Bad, and the Ugly

My previous post has gotten a lot of great feedback . Thanks everybody! I got some more important roadblocks

# Rendering ASP.NET Controls out of order

Friday, September 07, 2007 6:51 PM by Infinities Loop

I receive a lot of comments and emails stemming from my series of articles on understanding the nuances

# Ajout de controle dynamique dans une page ASP.net

Tuesday, September 18, 2007 5:02 AM by Atteint de Javascriptite aiguë [Cyril DURAND]

On me pose souvent des questions sur l'ajout de contrôle dynamique dans une page ASP.net. Par exemple,

# On dynamically creating server controls

Friday, September 28, 2007 7:05 AM by Atanas Korchev

Every once in a while I see code which looks like that:public class MyCustomControl : WebControl{ protected...

# re: TRULY Understanding Dynamic Controls (Part 1)

Friday, September 28, 2007 11:56 PM by msm

I think it to add a row when i  click the button of page .but it does't work

protected   System.Web.UI.WebControls.TableRow     newRow()

       {

               System.Web.UI.WebControls.TableRow   myr   =   new   TableRow();

               System.Web.UI.WebControls.TableCell   mycell1   =   new   TableCell();

               System.Web.UI.WebControls.TableCell   mycell2   =   new   TableCell();

               mycell2.Text   =   "sdfsdf";

               myr.Cells.Add(mycell1);

               myr.Cells.Add(mycell2);

               return   myr;

       }

 protected   void   Button1_Click(object   sender,   EventArgs   e)

       {

               System.Web.UI.WebControls.TableRow   myrow   =   this.newRow();

               this.Table1.Rows.Add(myrow);

       }

# Understanding Dynamic ASP.NET Controls

Wednesday, October 03, 2007 11:22 AM by Joe On ASP.NET

I was working on a demo of using MS AJAX and Dynamically adding ASP,NETControls to a page when I can

# Understanding Dynamic ASP.NET Controls

Wednesday, October 03, 2007 11:22 AM by Joe On .NET

Understanding Dynamic ASP.NET Controls

# Understanding Dynamic ASP.NET Controls

Wednesday, October 03, 2007 11:23 AM by Joe Stagner - Frustrated by Design !

I was working on a demo of using MS AJAX and Dynamically adding ASP,NETControls to a page when I can

# Techy News Blog &raquo; Understanding Dynamic ASP.NET Controls

Wednesday, October 03, 2007 11:37 AM by Techy News Blog » Understanding Dynamic ASP.NET Controls

Pingback from  Techy News Blog &raquo; Understanding Dynamic ASP.NET Controls

# re: TRULY Understanding Dynamic Controls (Part 1)

Wednesday, October 03, 2007 12:13 PM by Mussarat Aziz

Nice Shot...........:)

# Estrutura de Controles Din&#226;micos e o ASP.NET

Saturday, October 06, 2007 4:14 PM by Dennes

No Blog Infinities Loop foi publicada uma série de 5 artigos que explicam em inúmeros detalhes...

# re: TRULY Understanding Dynamic Controls (Part 1)

Thursday, November 15, 2007 4:57 AM by Kolik

Ох ты ебанаврот сколько всего написанО!!!

# ASP.NET: Dynamically Adding Controls &laquo; .NET Discussion

Friday, January 04, 2008 12:53 PM by ASP.NET: Dynamically Adding Controls « .NET Discussion

Pingback from  ASP.NET: Dynamically Adding Controls &laquo; .NET Discussion

# re: TRULY Understanding Dynamic Controls (Part 1)

Sunday, January 27, 2008 8:00 PM by Michael Holberton

Hi Dave,

I discovered this Blog when researching the reloading of a Dynamically added User Control and now it seems that maybe I don't need to follow that approach.

I have a lot of programming experience but still learning the ropes with .Net.

I still want to use a User Control, which contains a Label and a Repeater, because  I will want to use it on more than 1 page.

So, my question/comments regard the best way of controlling the Visibility/Performance of a Declared User Control and having it requery the database to rebuild the Repeater based on Criteria selected via other Controls on the Page.

I am going to attempt my own solution but I don't want to prompt you as to what that will be so that I can see what your initial approach, of someone with your experience, would be to my scenario.

When the Page is first loaded, the User Control should not be Visible. It should only become visible after a User has selected criteria and clicked on a button which will also activate the User Control to Bind/Rebind the Repeater.

Many Thanks,

Michael Holberton

Hospedaje Los Jardines & Sacred Valley Mountain Bike Tours

Cusco Database Development and Cycling Services E.I.R.L.

http://www.machawasi.com/

http://machawasi.blogspot.com/

databaseservices.blogspot.com

# re: TRULY Understanding Dynamic Controls (Part 1)

Sunday, January 27, 2008 8:29 PM by Michael Holberton

P.S. I forgot to add that I am using ASP.Net 1.1 with VB.Net

# TRULY Understanding ViewState, the comment index

Friday, February 22, 2008 6:43 PM by Infinities Loop

A long time ago I published one of my first blog entries, TRULY Understanding ViewState . And what an

# 深入理解 ASP.NET 动态控件

Sunday, March 30, 2008 2:49 AM by lsjwzh

深入理解ASP.NET动态控件(Part1-感性认识)

深入理解ASP.NET动态控件(Part2-编译过程)

深入理解ASP.NET动态控件(Part3-...

Leave a Comment

(required) 
(required) 
(optional)
(required)