How to create templated ASP.NET controls

In my old blog, I had a post that explained this – but that post didn’t get transferred over here. That old post was referenced by a lot of websites and blogs, and I get regular e-mails by people asking where they can find this post.
 
So – by request, here is the concept of what I wrote about this topic. I’ve created an example – let’s say you you want to create a UserControl that has an area for a title, and an area for the content. Let’s say you want to be able to declare this user control like this:
 

    <uc1:TitleTextControl ID="TitleTextControl1" runat="server"

        TitleAreaCssClass="Header" TextAreaCssClass="Outline">

        <TitleArea>Test title</TitleArea>

        <TextArea>

            Text area

            <asp:Label runat="server" ID="label1">You can put any controls in here.</asp:Label>

        </TextArea>

    </uc1:TitleTextControl>

Here is basically how you do that. First, you create a user control (Add New Item… > Web User Control…). In the designer, layout how you want the title area and text area to be:
 

    <%@ Control Language="C#" AutoEventWireup="true"

        CodeBehind="TitleTextControl.ascx.cs"

        Inherits="TemplatedControlsExample.TitleTextControl" %>

    <table>

    <tr>

        <td id="titleTD" runat="server"></td>

    </tr>

    <tr>

        <td id="textTD" runat="server"></td>

    </tr>   

    </table>

 
Note that I made the TD containers into server-side controls – this is so we have programmatic access to them later. So now, we want to write up ITemplate properties, to write their contents to inside those TD’s. So here is the code-behind for the user control:
 

    /// <summary>

    /// User control to show how to add templated properties.

    /// </summary>

    [ParseChildren(true)]

    public partial class TitleTextControl : System.Web.UI.UserControl, INamingContainer

    {

        protected void Page_Load(object sender, EventArgs e)

        {

        }

 

        /// <summary>

        /// The CSS class to use for the title area.

        /// </summary>

        public string TitleAreaCssClass

        {

            get { return this.titleTD.Attributes["class"]; }

            set { this.titleTD.Attributes["class"] = value; }

        }

 

        /// <summary>

        /// The CSS class to use for the text area.

        /// </summary>

        public string TextAreaCssClass

        {

            get { return this.textTD.Attributes["class"]; }

            set { this.textTD.Attributes["class"] = value; }

        }

 

        /// <summary>

        /// The Template property for the title area.

        /// </summary>

        [PersistenceMode(PersistenceMode.InnerProperty)]

        [TemplateContainer(typeof(INamingContainer))]

        public ITemplate TitleArea

        {

            get { return _titleArea; }

            set { _titleArea = value; }

        } ITemplate _titleArea;

 

        /// <summary>

        /// The Template property for the text area.

        /// </summary>

        [PersistenceMode(PersistenceMode.InnerProperty)]

        [TemplateContainer(typeof(INamingContainer))]

        public ITemplate TextArea

        {

            get { return _textArea; }

            set { _textArea = value; }

        } ITemplate _textArea;

 

        /// <summary>

        /// Default implementation for initializing the templated parts

        /// </summary>

        protected override void CreateChildControls()

        {

            if (TitleArea != null)

                TitleArea.InstantiateIn(this.titleTD);

 

            if (TextArea != null)

                TextArea.InstantiateIn(this.textTD);

 

            base.CreateChildControls();

        }

    }

Now, when I add this user control to a web form, I declare it as described above. Intellisense shows use the two template areas (called TitleArea and TextArea). So using that example from the top of this post, this renders a page like this:
 

  <table>

    <tr>

      <td id="TitleTextControl1_titleTD" class="Header">Test title</td>

     </tr>

    <tr>

      <td id="TitleTextControl1_textTD" class="Outline">

        Text area

        <span id="TitleTextControl1_label1">You can put any controls in here.</span>

      </td>

     </tr>

  </table>

So that’s basically it. There is some written up on this – but this tempating technique is usually only documented with Composite Controls – but as you see, can be useful and quite easy to implement for User Controls as well.
 
Posted in ASP.NET, Uncategorized

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Archives
Categories

Enter your email address to follow this blog and receive notifications of new posts by email.

Join 5 other followers

%d bloggers like this: