How to: Create Templated ASP.NET User Controls

You can create user controls that implement templates, an ASP.NET feature that allows the separation of control data from its presentation. A templated control does not provide a user interface. Instead, it is written to implement a naming container and to include a class whose properties and methods are accessible to the host page. For more information, see Template Sets and Templated Controls.

The user interface for the user control is supplied by a page developer at design time. The developer creates templates of the type defined by the user control, and can then add controls and markup to the templates.

To create a templated user control

  1. In the .ascx file, add an ASP.NET PlaceHolder control where you want the template to appear.

  2. In the user control's code, implement a property of type ITemplate.

  3. Define a server control class that implements the INamingContainer interface as a container in which to create an instance of the template. This is called the template's naming container.

    Note

    This control essentially becomes a nested class of the user control, though this is not required.

  4. Apply the TemplateContainerAttribute to the property that implements ITemplate and pass the type of the template's naming container as the argument to the attribute's constructor.

  5. In the control's Init method, repeat the following steps one or more times:

    • Create an instance of the naming container class.

    • Create an instance of the template in the naming container.

    • Add the naming container instance to the Controls property of the PlaceHolder server control.

      Note

      From the point of view of the page using the user control, the syntax for the templated user control is identical to what it would be with a custom templated control.

Example

The following example shows a templated user control and a page that contains it. The user control creates a template that can be declared on a host page as <MessageTemplate>. The template control also exposes two properties, Index and Message, that the host page can access inside the template.

The first sample shows the templated user control. The second sample shows a page that contains the user control.

Note

Templated ASP.NET user controls are not supported in the Visual Studio designer. However, you can compile and run this example in Visual Studio. To do so, when you create ASP.NET pages to test this code, replace all the designer-generated code in the pages with the code and markup in the example listings.

<%@ Control language="VB" ClassName="TemplatedUC" %>
<%@ Import Namespace="System.ComponentModel"  %>

<script runat="server" >
    Private m_messageTemplate As ITemplate = Nothing
    <TemplateContainer(GetType(MessageContainer))> _
    <PersistenceMode(PersistenceMode.InnerProperty)> Public Property _
            MessageTemplate() As ITemplate
        Get
            Return m_messageTemplate
        End Get
        Set(ByVal value As ITemplate)
            m_messageTemplate = Value
        End Set
    End Property
    
    Sub Page_Init()
        If Not (MessageTemplate Is Nothing) Then
            Dim i As Integer
            Dim fruits() As String = _
                {"apple", "orange", "banana", "pineapple"}
            For i = 0 To 3
                Dim container As New MessageContainer(i, fruits(i))
                MessageTemplate.InstantiateIn(container)
                PlaceHolder1.Controls.Add(container)
            Next i
        End If
    End Sub

    Public Class MessageContainer
        Inherits Control
        Implements INamingContainer

        Private m_index As Integer
        Private m_message As String
        Friend Sub New(ByVal i As Integer, ByVal msg As String)
            Me.Index = i
            Me.Message = msg
        End Sub
    
        Public Property Index() As Integer
            Get
                Return m_index
            End Get
            Set(ByVal value As Integer)
                m_index = value
            End Set
        End Property

        Public Property Message() As String
            Get
                Return m_message
            End Get
            Set(ByVal value As String)
                m_message = value
            End Set
        End Property
    End Class
</script>
<asp:Placeholder runat="server" ID="PlaceHolder1" />
<%@ Control language="C#" ClassName="TemplatedUC" %>
<%@ Import Namespace="System.ComponentModel"  %>
<script runat="server">
private ITemplate messageTemplate = null;

[ TemplateContainer(typeof(MessageContainer)) ]
[ PersistenceMode(PersistenceMode.InnerProperty) ]
public ITemplate MessageTemplate {
    get 
    { 
        return messageTemplate; 
    }
    set 
    { 
        messageTemplate = value; 
    }
}

void Page_Init() {
    if (messageTemplate != null) {
        String[] fruits = {"apple", "orange", "banana", "pineapple" };
        for (int i=0; i<4; i++) 
        {
            MessageContainer container = new MessageContainer(i, fruits[i]);
            messageTemplate.InstantiateIn(container);
            PlaceHolder1.Controls.Add(container);
        }
    }
}

public class MessageContainer: Control, INamingContainer {
    private int m_index;
    private String m_message;
    internal MessageContainer(int index, String message)
    { 
        m_index = index;
        m_message = message;
    }
    public int Index {
        get 
        { 
            return m_index; 
        } 
    }
    public String Message 
    { 
        get 
        { 
            return m_message; 
        } 
    }
}
</script>
<asp:Placeholder runat="server" ID="PlaceHolder1" />
<%@ Page Language="VB" %>
<%@ Register TagPrefix="uc" tagname="TemplateTest" 
    Src="TemplatedUC.ascx" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
    "https://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="https://www.w3.org/1999/xhtml">
<script runat="server">
    Sub Page_Load()
        DataBind()
    End Sub
</script>
<head>
<title>Templated User Control Test</title>
</head>
<body>
<h1>Testing Templated User Control</h1>
<form id="Form1" runat="server">
<uc:TemplateTest runat="server">
  <MessageTemplate>
    Index: <asp:Label runat="server" ID="Label1" 
                Text='<%# Container.Index %>' />
    <br />
    Message: <asp:Label runat="server" ID="Label2" 
        Text='<%# Container.Message %>' />
    <hr />
  </MessageTemplate>
</uc:TemplateTest>
</form>
</body>
</html>
<%@ Page Language="C#" %>
<%@ Register TagPrefix="uc" tagname="TemplateTest" 
    Src="TemplatedUC.ascx" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
    "https://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="https://www.w3.org/1999/xhtml">
<script runat="server">
    protected void Page_Load()
    {
        DataBind();
    }
    
</script>
<head>
<title>Templated User Control Test</title>
</head>
<body>
<h1>Testing Templated User Control</h1>
<form id="Form1" runat="server">
<uc:TemplateTest runat="server">
  <MessageTemplate>
    Index: <asp:Label runat="server" ID="Label1" 
        Text='<%# Container.Index %>' />
    <br />
    Message: <asp:Label runat="server" ID="Label2" 
        Text='<%# Container.Message %>' />
    <hr />
  </MessageTemplate>
</uc:TemplateTest>
</form>
</body>
</html>

See Also

Concepts

ASP.NET User Controls Overview

Template Sets and Templated Controls