views:

282

answers:

1

I would like to be able to do something like:

<ui:Tab Title="A nice title">
  <TabTemplate>
    <asp:Literal runat="server" ID="SetMe">With Text or Something</asp:Literal>
  </TabTemplate>
</ui:Tab>

but also be able to do:

<ui:Tab Title="A nice title">
  <TabTemplate>
    <asp:DataList runat="server" ID="BindMe"></asp:DataList>
  </TabTemplate>
</ui:Tab>

Answer code I eventually came up with:

[ParseChildren(true)]
public class Node : SiteMapNodeBaseControl, INamingContainer
{
    private ITemplate tabTemplate;
    [Browsable(false),
    DefaultValue(null),
    Description("The tab template."),
    PersistenceMode(PersistenceMode.InnerProperty),
    TemplateContainer(typeof(TabTemplate))]
    public ITemplate TabTemplate
    {
     get { return tabTemplate; }
     set { tabTemplate = value; }
    }
 protected override void CreateChildControls()
 {
  if (TabTemplate != null)
  {
   Controls.Clear();
   TabTemplate i = new TabTemplate();
   TabTemplate.InstantiateIn(i);
   Controls.Add(i);
  }
 }
 protected override void Render(HtmlTextWriter writer)
 {
  EnsureChildControls();
  base.Render(writer);
 }
}


public class TabTemplate : Control, INamingContainer
{
}
+1  A: 

The ParseChildren attribute tells .NET whether to treat your control's children as properties or as controls. For your first example, you want to treat children as controls, so add

[ ParseChildren(ChildrenAsProperties = false) ]

For the second, you want ChildrenAsProperties=true, and a TabTemplate property of type ITemplate. There's some plumbing involved after that, which this MSDN sample describes. It doesn't add a lot of value if you only need one template, though.

stevemegson
I pasted what I've got so far. Almost... :P
rball