tags:

views:

230

answers:

1

Hi.

I'm playing around with a composite control that uses the ASP.NET templating system.

I want to be able to define a HeaderTemplate and a FooterTemplate in my markup, and programmatically add a usercontrol between the two.

The markup I'm aiming for is something like this:

<asp:DropZone runat="server" ID="LeftZone">
   <HeaderTemplate>
      <h1>Getting started</h1>
   </HeaderTemplate>
   <FooterTemplate>
      <h3>The end of it...</h3>
   </FooterTemplate>
</asp:DropZone>

My DropZone class looks like this:

public class DropZone : Control, INamingContainer
    {
        private ITemplate headerTemplate;
        private ITemplate footerTemplate;

        [DefaultValue((string)null), Browsable(false), PersistenceMode(PersistenceMode.InnerProperty), TemplateInstance(TemplateInstance.Single)]
        public virtual ITemplate HeaderTemplate
        {
            get { return headerTemplate; }
            set { headerTemplate = value; }
        }

        [DefaultValue((string)null), Browsable(false), PersistenceMode(PersistenceMode.InnerProperty), TemplateInstance(TemplateInstance.Single)]
        public ITemplate FooterTemplate
        {
            get { return footerTemplate; }
            set { footerTemplate = value; }
        }

        protected override void OnInit(EventArgs e)
        {
            EnsureChildControls();
            base.OnInit(e);
        }

        private void AppendTemplate(ITemplate template, Control container)
        {
            if (template == null) return;

            var ph = new PlaceHolder();
            container.Controls.Add(ph);
            template.InstantiateIn(ph);
        }

        protected override void CreateChildControls()
        {
            Controls.Clear();

            AppendTemplate(HeaderTemplate, this);

            Control helloWorld = Page.LoadControl("~/WebParts/HelloWorld.ascx");
            if (helloWorld != null)
            {
                Controls.Add(helloWorld);
            }

            AppendTemplate(FooterTemplate, this);

            ChildControlsCreated = true;
            base.CreateChildControls();
        }
    }

However, this does not work as the ITemplate fields are never instantiated.

Any help or guidance would be highly appreciated.

Thanks.

UPDATE: I had to derive my custom control from CompositeControl to get things work as expected.

+1  A: 

See (for instance) Templated Server Control Example, and MSDN Search for "asp.net templated controls".

John Saunders
Thank you. Apparently I have to derive my DropZone control from CompositeControl instead of just Control - now everything works as expected.
Peter Lindholm
Ah, yes. CompositeControl is your friend.
John Saunders