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

Comments

Sönke 21 Jan 2008

Thx for this one. Works nicely.

Anyway the “Designer” in Visual Studio won’t display the UserControl due to the error: “System.Web.UI.UserControl has no public property called Template” (translated error message, therefor not precise)

Does this work with your example?