Share via


Developing a Templated Control

ASP.NET provides a versatile feature called templates that allows the separation of control data from its presentation. A templated control does not itself provide a user interface (UI). The UI for the control is supplied by a page developer through inline templates which allow a page developer to customize the UI for the control. If you are not familiar with templates in ASP.NET, see the example in the ASP.NET QuickStart —> ASP.NET Web Forms —> Data Access and Customization —> Introduction to Templated Controls.

To develop a templated control

  1. Implement the System.Web.UI.INamingContainer interface. This is a marker interface that does not have any methods. It creates a new naming scope under your control so that child controls have unique identifiers in the naming tree.

    public class TemplatedFirstControl : Control,INamingContainer 
    {...}
    
  2. Apply the ParseChildrenAttribute to your control and pass true as the argument. This indicates to the page parser how to parse the template property tags when your control is used declaratively on an ASP.NET page. Step 3 shows how to define a template property.

    Note   If your control derives from WebControl you do not need to apply the ParseChildrenAttribute because WebControl is already marked with this attribute.

    [ ParseChildren(ChildrenAsProperties = true)]
    public class TemplatedFirstControl : Control, INamingContainer {...}
    

    For more information about ParseChildrenAttribute, see Using ParseChildrenAttribute.

  3. Define one or more properties of type System.Web.UI.ITemplate. ITemplate has a method, InstantiateIn, that creates controls using the template supplied inline on the page. You do not have to implement the InstantiateIn method; the ASP.NET page framework provides the implementation. An ITemplate property must have a metadata attribute of type System.Web.UI.TemplateContainerAttribute that indicates which INamingContainer control will hold the instantiated template. This is explained in step 4. The following code fragment defines a template property.

    [TemplateContainer(typeof(FirstTemplateContainer))]                 
     public ITemplate FirstTemplate {...}
    
  4. The argument of the TemplateContainerAttribute is the type of the container control within which you want the template to be instantiated. The container control is independent of the templated control that you are authoring. The reason for having a logical container is that a templated control often has a template that needs to be repeatedly instantiated with different data. Having a container control that is different from the root templated control makes it possible to have such multiple instances. The logical container is the immediate INamingContainer of the child controls within the template. This relationship is explained in greater detail in Developing a Templated Data-Bound Control.

    Note   The container control itself must implement INamingContainer since it has child controls that need to be named uniquely on a page.

    public class FirstTemplateContainer : Control, INamingContainer {...}
    
  5. Override the CreateChildControls method to create the child controls in the template. This is done in three steps.

    1. Instantiate the template container.
    2. Invoke the InstantiateIn method of the template property and pass the container to it as an argument. The InstantiateIn method (declared in the ITemplate interface) instantiates the elements of the template as child controls of the template container. You do not have to implement the InstantiateIn method; the ASP.NET page framework provides the implementation.
    3. Add the instance of the template container to the Controls collection of your templated control.

    The following code fragment shows an implementation of CreateChildControls.

    private Control myTemplateContainer;
    
    protected override void CreateChildControls ()          
    {
       if (FirstTemplate != null)
       {
          myTemplateContainer = new FirstTemplateContainer(this);
             FirstTemplate.InstantiateIn(myTemplateContainer);
          Controls.Add(myTemplateContainer);
        }
        else
        {
            Controls.Add(new LiteralControl(Text + " " + DateTime));
        }
     }
    
    
  6. Override the OnDataBinding method inherited from Control to invoke the EnsureChildControls method. This guarantees that child controls in the template are created before the page framework tries to evaluate any data-binding expressions within the template. You must also call the OnDataBinding method of the base class to ensure that registered event handlers are invoked.

            protected override void OnDataBinding(EventArgs e) {
                EnsureChildControls();
                base.OnDataBinding(e);
            }
    
  7. In step 5, repeat the logic within the CreateChildControls method to instantiate a template for each of the template properties of your control.

For examples of a templated control, an associated container control for the template, and a page that uses the control, see Templated Control Sample.

See Also

Templated Control Sample