Build a Basic Template Control

Take charge of your Web pages’ layout.

If you have been working withASP.NET even for a little while, you've probably encountered a template control, though you might not have realized it. Template controls are server controls, inside which you can specify the HTML layout of one or more templates. This gives you flexibility when using the control while maintaining the control's functionality. You can use template controls to create standard layouts for information on a Web site or to provide a control that enables variations on a single layout.

Server controls such as Repeater, DataList, and DataGrid fall into the template control category. More specifically, these are data-bound template controls. In this column I'll show you how to build a basic template control (the downloadable source code for this article is available in both C# and Visual Basic .NET.)

A template control lets you control the layout of the rendered HTML by defining the layout of a template within the control itself, as shown here:



  

    Title
This is the ItemTemplate area

This control would be rendered with any HTML defined in the control itself as well as the HTML between the and tags within the control. You can use this capability when you have a prescribed format for rendering information, although the information itself might change. For example, you could use a template control if company policy dictates that all information related to currency conversion be shown in an HTML table, with a header row displaying the text "Currency Information", a row displaying the information, and a row displaying some copyright information. Creating and using a template control in a scenario like this ensures all information related to currency conversion is displayed in the approved format (see Figure 1).


Figure 1. The CurrencyInformation template control consists of a predefined header and footer row, with an ItemTemplate in the middle. In this figure, the ItemTemplate contains data about a currency conversion request.

 

Build the Control Structure

The CurrencyInformation control shown in Figure 1 is a basic template control. In this case, the CurrencyInformation control contains only one template - the ItemTemplate. The DataGrid exposes a HeaderTemplate, FooterTemplate, ItemTemplate, and AlternatingItemTemplate, so you can construct any of these templates. The header and footer rows of the CurrencyInformation control are predefined within the control, providing a predefined table structure for displaying information. An instance of the CurrencyInformation control with nothing in the ItemTemplate is shown in Figure 2.

 


Figure 2. When the ItemTemplate is empty, the control is rendered showing only the header and footer rows. This figure shows how the predefined portions of the control are rendered regardless of what is in the ItemTemplate.

The CurrencyInformation control exposes only a single property: ItemTemplate. The ITemplate interface is used as the property's data type, which lets you specify the template HTML either programmatically or declaratively.

The basic structure for the CurrencyInformation control is shown in Figure 3.

using System;

using System.Web.UI;

using System.Web.UI.HtmlControls;

using System.Web.UI.WebControls;

using System.ComponentModel;

 

namespace MyTemplateControls

{

   [ToolboxData(

    "<{0}:CurrencyInformation runat=server>" +

    ""

)]

  public class CurrencyInformation :

    System.Web.UI.WebControls.WebControl,

    INamingContainer

  {

    //Properties go here

 

    //Methods go here

  }

}

Figure 3. The CurrencyInformation template control derives from the System.Web.UI.WebControls.WebControl class and implements the INamingContainer interface. I've added comments indicating when the code in the upcoming listings will be added.

Now I'll tell you about each part of the control. Notice that, like other custom controls, the CurrencyInformation control derives from the System.Web.UI.WebControls.WebControl class. This class provides all the basic functionality of a WebControl without having to write it yourself. Also, the CurrencyInformation control implements the INamingContainer interface, which ensures all child controls are uniquely named. The ID of the child control is appended with the parent control ID and an underscore ("CurrencyInformation1_Control1"). The ToolboxData attribute is applied to the class. This attribute, which is not required, defines how the code will look in a Web form when the control is dragged from the Toolbox to the Web form in Visual Studio .NET.

 

Expose Templates as Properties

The ITemplate interface serves as the data type for any property in the control that is a template. This lets you expose the templates as properties of the control so other developers can define the template HTML either programmatically or declaratively. See Figure 4 for the definition of the ItemTemplate property.

//C# Syntax

private ITemplate _itemTemplate;

[TemplateContainer(typeof(CurrencyInformation))]

public ITemplate ItemTemplate

{

  get{return _itemTemplate;}

  set{_itemTemplate = value;}

}

 

'Visual Basic .NET syntax

Private _itemTemplate As ITemplate

 _

Public Property ItemTemplate() As ITemplate

  Get

    Return _itemTemplate

  End Get

 

  Set(ByVal Value As ITemplate)

    _itemTemplate = Value

   End Set

End Property

Figure 4. The ItemTemplate property uses the ITemplate interface as its data type, which enables the control to use the code inside the template tags, and at run time, render that content inside the control layout.

The ITemplate interface defines how to add the template HTML to the control. This interface defines a single method, InstantiateIn, which creates the template HTML that is passed in the control as an argument to the method:

Panel itemContainer = new Panel();

_itemTemplate.InstantiateIn(itemContainer);

This code creates a Panel control and instantiates the template HTML inside Panel. This is the sole purpose of the ITemplate interface. The ASP.NET Framework implements the ITemplate interface, which is never implemented directly by a class.

 

Override the CreateChildControls Method

The heart of building a template control is in the CreateChildControls method. You override this method and build the control structure, instantiating the template in the appropriate place. For the CurrencyInformation template, you must first build the table structure and the header row. Next, you instantiate the template in a Panel control and add the Panel control to the second row of the table. Finally, you create the footer row and add the table to the parent control's Controls collection. The CreateChildControls method is shown in Figure 5.

protected override void CreateChildControls()

{

  //Create the top-level Table object

  HtmlTable t = new HtmlTable();

  t.Width = this.Width.ToString();

  t.CellPadding = 4;

  t.CellSpacing = 0;

  t.Border = 0;

  t.Attributes["style"] = "border-width:1px;" +

Use a Template Control on a Web Form

You can use the CurrencyInformation control in a Web application by making a reference to the MyTemplateControls assembly. In Visual Studio .NET, you add a reference by selecting Add Reference under the Project menu. This action makes a copy of MyTemplateControls.dll in the Web application's \bin directory. If you are not using Visual Studio .NET, you can copy the MyTemplateControls.dll to your Web application's \bin directory.

In the Web form, you register the assembly on the page using the @ Register directive:

<%@ Register TagPrefix="cc1"

 Namespace="MyTemplateControls"

 Assembly="MyTemplateControls" %>

Once the control is registered, you can use it on the Web form like any other server control. Here is the code for using the CurrencyInformation control and filling the ItemTemplate with declarative text:



  

    Disclaimer: Currency conversions are

    provided as a sample and are not necessarily guaranteed

    to be accurate. The MoneyUtilities Web service is

    provided by DotNetJunkies.com with no guarantees or

    warranties.

  

You can place static text inside the ItemTemplate; this text is rendered inside the control. You define the CurrencyInformation control as you do any other server control, by specifying the TagPrefix and TagName and adding the runat="server" attribute. Inside the control tags, you define the template by using the property name (). Inside the item template, you simply add some text.

You also can use other server controls inside the template (see Figure 6).





    From:

    

    
From Amount:
To:
To Amount:
Conversion Date:

Figure 6. You can use ASP.NET server controls or other custom server controls inside the ItemTemplate. These controls process normally, but their output is rendered inside the template control.

In the Web form's codebehind, you can retrieve currency conversion information dynamically and populate the server controls in the template. The key thing to remember is the server controls in the template are child controls of the CurrencyInformation control. Just as controls embedded in a DataGrid can't be accessed directly in Web form codebehind, neither can the server controls in the CurrencyInformation control. Instead, you need to use the Control.FindControl method. This method is inherited into the CurrencyInformation control because it derives from WebControl, which in turn derives from Control.

The FindControl method takes an ID value as a String and returns a Control instance if it finds a matching control. Once the control is found, it needs to be cast as its particular control type before you can access its properties. For this example, you access the DotNetJunkies.com MoneyUtilities Web service and execute a currency conversion. Then you set the properties of the server controls in the template (see Figure 7).

private void btnGo_Click(object sender, System.EventArgs e)

{

  com.dotnetjunkies.www.MoneyUtilities mu =

    new com.dotnetjunkies.www.MoneyUtilities();

  com.dotnetjunkies.www.Conversion c;

  c = mu.ConvertMoney(

    Single.Parse(txtAmount.Text.Trim()),

    ddlFrom.SelectedItem.Value,

    ddlTo.SelectedItem.Value

  );

 

   ((Label)CI1.FindControl("lblFrom")).Text =

     c.FromMoneyType;

   ((Label)CI1.FindControl("lblTo")).Text =

    c.ToMoneyType;

   ((Label)CI1.FindControl("lblFromAmount")).Text =

    c.FromAmount.ToString("n");

   ((Label)CI1.FindControl("lblToAmount")).Text =

    c.ToAmount.ToString("n");

   ((Label)CI1.FindControl("lblDate")).Text =

    c.ConversionDate;

}

Figure 7. To access the controls in the ItemTemplate from a Web form code-behind class, you must use the FindControl method. This method locates the control by its ID value and returns it as an instance of the Control class. Once the control is found, you must cast it back to its correct data type before accessing its properties and methods.

In the preceding example, the Web form contains two DropDownLists, a TextBox, a LinkButton, and the CurrencyInformation control. The user selects two countries from the DropDownLists and enters an amount into the TextBox. When the user clicks on the LinkButton, the DotNetJunkies.com MoneyUtilities proxy class is instantiated and the ConvertMoney method is executed. Once the Web method completes, you use the FindControl method to locate the appropriate Label controls and set their Text properties with the appropriate values. The result is shown in Figure 8.

 


Figure 8. The CurrencyInformation control can be used in a variety of ways. In this figure, you can see the control used with some ASP.NET server controls in the ItemTemplate and the control with static text in the ItemTemplate.

You can use these concepts to build countless template controls with one, two, or any number of templates within them. This is simply one example of control development in ASP.NET, which offers vast possibilities when you use your imagination.

The code referenced in this article is available for download.

 

Doug Seven is a co-founder of DotNetJunkies (http://www.dotnetjunkies.com), a .NET training company. He has had previous technical roles at Nordstrom, Microsoft, and GiftCertificates.com, and he has experience as a training specialist at Seattle Coffee Company. Doug co-authored Programming Data-Driven Web Applications with ASP.NET and ASP.NET: Tips, Tutorials & Code (Sams), and Professional ADO.NET and Professional ASP.NET Security (Wrox). E-mail Doug at mailto:[email protected].

Tell us what you think! Please send any comments about this article to [email protected]. Please include the article title and author.

Hide comments

Comments

  • Allowed HTML tags: <em> <strong> <blockquote> <br> <p>

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
Publish