Sunday, September 28, 2008
Adding ASP.NET Controls programmatically
If you design ASP.NET Web Controls or Composite Controls, you have designed controls programmatically. This approach is not as easy as using the Visual Designer in Visual Studio. This post explores the use of the "C class", which is part of the COR download. The "C class" is a set of public static methods for adding Controls, managing strings, XML files and more.
Personally, once I started designing Web Parts, I did not want to go back to designing controls using the Visual Designer. I actually find it easier to place controls on the page and use logic to decide what controls are being placed on the page. However, designing Web Parts with standard Web Controls leads to much code. The "C class" allows design of controls with minimum code.
// Let's review how a Label is added to a control:
Label label = new Label();
Label.ID = "ThisLabel";
label.Text = "The name to display";
label.Width = Unit.Pixel(200);
label.CssClass = "AFormatOption";
this.Controls.Add(label);
It takes five statements just to add a simple label. For complex GUI's, it is easy to get lost in the number of lines required. I started thinking: "Why not have a simple method that adds the Label with a number of parameters?". E.g. Let's review what such a method would look like.
// Using a method that does the work of assigning the values to the named properties
Label label = AddLabelMethod("ThisLabel", "The name to display", "AFormatOption", Unit.Pixel(200), this);
The AddLabelMethod takes five parameters: ID, Text, CssClass, Width and an object that the label control is added to. The AddLabelMethod returns the new label object, which typically is not required because all the work is done in the AddLabelMethod.
The C class in COR is a set of helper methods that simplify the addition of Web Controls. To add a label,
// Using the AddLabel method is the C class simplifies programmatic design.
Label label = C.AddLabel ("ThisLabel", "The name to display", "", "AFormatOption", Unit.Pixel(200), this);
Note: ToolTip is added to the list of parameters. It is shown as a blank string in the example.
The C class, over 2000 lines of code at last count, contains a number of useful methods, including:
- AddTable, NewTableRow, NewTableCell
- AddLabel, AddTextBox, AddLinkLabel, and a lot more
- AddHiddenField and other methods to get and set the value of the hidden field
- Xml file management, e.g. GetAttribute, ReadXmlFile
- AddUpdatePanel, AddUpdateProgress, AddTimer (recent additions)
- ... and more
I find using tables to place controls on the page is now simple. E.g
// Add a table to this control
Table table = C.AddTable("table", Unit.Percentage(100), this);
// Add the first Row
TableRow row = C.NewTableRow(table);
// Add the first cell to the Row – it has text and a tooltip and is 100 pixels wide.
C.NewTableCell(row, Unit.Pixel(100), "a name to display", "a tooltip for the cell", "CellFormat");
// Add a second cell to the Row.
TableCell cell = C.NewTableCell(row);
// Add a text box to the second cell
C.AddTextBox("tb2", "", "Enter the name of something", "TextBoxFormat", Unit.Pixel(200), cell);
Using ASP.NET controls, this five-line sample would have taken about 20 lines of code. This approach has clear advantages:
- Reduced footprint – The number of lines makes it easier to understand what is being done.
- It is easier to add Comments that relate to what is being done.
- The C class methods prompt the user for the typically used parameters. It is now easy to identify if any of the typical parameters have been forgotten.
The "C class" is available in the COR download found on Code Plex.
Related posts include: ASP.NET Life Cycle.
Labels: ASP.net
The Life Cycle of ASP.NET Controls
Designing ASP.NET websites is easier if you understand the Life Cycle of the ASP.NET controls. Let's review the ASP.NET controls (Refer to table 1). These include:
- Page (Master Page)
- User Control
- Web Control
- Html Control
- Composite Control
- Web Part
From an object model perspective, the Life Cycle methods are derived from Control, Web Control and Composite Control.
The table presents ASP.NET controls mapped against Life Cycle methods. This is what I think of as the 'get started' Life Cycle for controls. There are more Life Cycle methods, e.g. Pre-Init, if you want to manage Master Pages and Themes for a page. Here are some observations:
- You don't need to use all of the states when writing a control
- You are best served if you match functionality to the correct Life Cycle method
- Your control will behave properly in all use cases.
- Subtle bugs can occur because you have placed functionality in a non-optimal Life Cycle method
- Your control will behave properly in all use cases.
Life Cycle Method | Member of | Page, User Control | Web Control | Composite Control, Web Part | Html Control |
Inherits from -> | X | Control – Template Control | Control | Control – Web Control | Control |
Init | Control | 1 | 1 | 1 | 1 |
Load Control State | Control | 2 | 2 | 3 | 2 |
Load View State | Web Control | 3 | 3 | 4 | |
Load | Control | 4 | 4 | 5 | 3 |
Create Child Controls | (Composite) Control | 2 or 6 (See Note 1) | |||
Post back Event Handling | Web Control | 5 | 5 | 7 | 5 |
Pre Render | Control | 6 | 6 | 8 | 6 |
Save Control State | Control | 7 | 7 | 9 | 7 |
Save View State | Web Control | 8 | 8 | 10 | |
Render | Web Control | 9 | 9 | 11 | |
Dispose | Control | 10 | 10 | 12 | 8 |
Unload | Control | 11 | 11 | 13 | 9 |
Table 1: Life Cycles of various ASP.NET Controls
Controls and the Life Cycle
Html Controls are simple controls that inherit from Control. As such, valid Life Cycle methods include:
- Init
- Load Control State
- Load
- Post back event handling
- Pre Render
- Save Control State
- Dispose
- Unload
Page, User Control and Web Control includes the methods above, plus:
- Load View State
- Save View State
- Render
The Composite Control and Web Part include the base methods from above, plus:
- Create Child Controls
Composite Controls
Being a Web Part designer means that I use Composite Controls. Composite Controls are different in that they have a Life Cycle method called 'CreateChildControls'. (This is probably because of the history of Web Parts and SharePoint.) Here are a couple of notes from MSDN documentation on Composite Controls.
The CompositeControl class is new in ASP.NET 2.0. If you created custom controls in ASP.NET version 1.0 or 1.1, you had to implement the INamingContainer interface to create a new naming scope for child controls. In addition, you had to override the Controls property and invoke the EnsureChildControls method. In ASP.NET 2.0, these and other steps are performed by the CompositeControl class.
You should create the child controls in the CreateChildControls method and not in OnInit or another life cycle phase. The server control architecture relies on calls to CreateChildControls whenever the Controls collection is needed, such as during data binding (if applicable).
Note 1: When the Composite Control is displayed normally, 'CreateChildControls' is called AFTER the 'Load' method. However, when a post back event occurs, 'CreateChildControls' is called AFTER the 'Init' method. This certainly makes the 'CreateChildControls' method an "interesting" aspect of the Life Cycle.
References
- http://blogs.thesitedoctor.co.uk/tim/2006/06/30/Complete+Lifecycle+Of+An+ASPNet+Page+And+Controls.aspx – this shows a trace of the Life Cycles of MasterPage, Page, and various Controls.
- http://msdn.microsoft.com/en-us/library/ms178472.aspx - this describes the Page Life Cycle.
Labels: ASP.net
Subscribe to Posts [Atom]
