Let’s introduce the simple code for adding controls that are in templates to the control collection:
[ParseChildren(true)]
[PersistChildren(false)]
public class SimpleTemplateControl : Control, INamingContainer {
private ITemplate pSimpleTemplate;
[Browsable(false)]
[PersistenceMode(PersistenceMode.InnerProperty)]
public ITemplate SimpleTemplate {
get { return pSimpleTemplate; }
set { pSimpleTemplate = value; }
}
protected override void CreateChildControls() {
Controls.Clear();
if (SimpleTemplate != null)
SimpleTemplate.InstantiateIn(this);
}
}
First, we will look at the attributes applied to the control. These attributes are required to be applied to the control class so the ASP.NET parser treats the text inside the control as part of the control; therefore, the page parser can designate the template to be “built”. These attributes are already implemented on the WebControl class so it may not be necessary for you to apply these attributes.
The template of the above example is the SimpleTemplate property. There is a Browsable attribute attached to the SimpleTemplate property to tell the IDE to that it may not be visible to the property explorer. The PersistanceMode attribute that is also applied to the SimpleTemplate property tells ASP.NET that the property’s contents (or template contents) can be placed as an inner property. Hence, we can get a simple mark-up for registering the control on the page.
<cc1:SimpleTemplateControl runat=server>
<SimpleTemplate>
Hi, I am inside a template. So is the text box:
<asp:TextBox runat=server />
</SimpleTemplate>
</cc1:SimpleTemplateControl>
This is where templates in server controls become a very familiar scene amongst the creation of composite server controls. Essentially, what the CreateChildControls method does now is tells the template to put the controls into the actual container control (the SimpleTemplateControl control in this case). In the CreateChildControls method, I checked if the template property was null (nothing in Visual Basic) before I called its only member (the InstantiateIn method). The reason for this is to check if a template has been built or not – by a control developer or the ASP.NET parser.
However, to explain the logic of the InstantiateIn method: this method is called by the container of the template. If the template has any controls to add to the container control, it has to be done over here and no where else. Basically, the templates in the containing controls are abstracts of controls but are not given life yet because it is not added to the page’s control tree – it is seen as part of the control. Once the InstantiateIn method is called, it is the templates chance to put the abstract controls that it contains into the page’s control tree; hence, giving the controls inside the template, the gift of life.
The parameter that is parsed in the InstantiateIn method is normally the container control which all the abstract controls are added to that control tree. The container control is normally the current control which has the INamingContainer interface applied… but nothing stops the container control to be another control inside the “current” server control (that is when there are “deep” composite controls).