UserControl template areas

ASP.NET smartie pants Scott Guthrie has linked to a really interesting article about supporting templated areas in ASP.NET controls. This is aimed at people doing user controls, but the same thing will work if you want to have a templated area in your own custom control.

I’ve created a little sample that shows how to do this in a composite control (which is all a user control really is) entirely in code. It’s basically exactly the same code, I just wanted to see if there would be any complications with it.

So I just need to build a C# class that has an ITemplate property and a place holder inside of it using all of the stuff in the tutorials:

// this attribute is important because it tells the
// ASP.NET parser that your tag in the ASP.NET page
// will contain nested tags inside it
[ParseChildren(true)]
public class TemplatedCustomControl : WebControl
{
    private Label Label;
    private PlaceHolder PlaceHolder;
    private ITemplate _template;

    protected override void CreateChildControls()
    {
        base.CreateChildControls();

        // create label and add to control's collection
       Label = new Label();
       Label.ID = "Label1";
       this.Controls.Add(Label);
       this.Controls.Add(new HtmlGenericControl("br"));

       // create placeholder area and add to control's collection
       PlaceHolder = new PlaceHolder();
       PlaceHolder.ID = "PlaceHolder1";
       this.Controls.Add(PlaceHolder);
    }

    protected override void OnInit(EventArgs e)
    {
        // call the template's instantiate in method
        // to actually instantiate all of the template's controls
        // in the placeholder's control container
        if (_template != null)
        {
            _template.InstantiateIn(PlaceHolder);
        }
        base.OnInit(e);
    }

    /// 
    /// Simple property to set the text of the label
    /// 
    public string Text
    {
        get
        {
            this.EnsureChildControls();
            return Label.Text;
         }
        set
       {
            this.EnsureChildControls();
            Label.Text = value;
        }
   }

    /// 
    /// Property to get access to the template of the control
    /// 
    [
    PersistenceMode(PersistenceMode.InnerProperty),
    TemplateContainer(typeof(TemplateControl))
    ]
    public ITemplate Template
    {
        get { return _template; }
        set { _template = value; }
    }
}

Then in the ASP.NET file I can put anything I like in the templated area and it’ll render on my page:

  1. <cc1 :TemplatedCustomControl ID="TemplatedCustomControl1" Text="Helen's templated conrol" runat="server">
  2.     <template>
  3.         My templated area:
  4.         <asp :TextBox ID="Textbox1" runat="server" />
  5.      </template>
  6. </cc1>

The most interesting part of this for me was seeing how the wire-up between template and area that displays the template works because I’ve actually had to create templates in code quite a few times and I’ve seen the InstantiateIn() method from the template class side of things. I guess I thought the calling of InstantiateIn() was some ASP.NET voodoo, while really it’s only a really simple line of code.

If you’re a VB.NET user or you just want another example to look at, there’s also an article on the MSDN which has the code you need in both VB.NET and C#.

Posted on 10 Jun 06 by Helen Emerson (last updated on 10 Jun 06).
Filed under Server controls