Composite Controls ”Key ConceptsA composite control contains two or more existing controls and reuses the implementation provided by the child controls to enable rendering, postback handling, and other functionality. Composition simplifies control development because it allows you to delegate many tasks to child controls. For example, when your control contains the standard TextBox control that can process postback data, you do not have to implement the IPostBackDataHandler interface. In a similar vein, you could use the existing Button control to capture form postback instead of implementing the IPostBackEventHandler interface. You can derive your composite control from the Control class or from the WebControl class. There are two key tasks that you must perform when implementing a composite control:
Let's examine the reasons for these implementation details. You must create your child controls in the CreateChildControls method ”instead of creating them in a specific phase such as Instantiate or Initialize ”so that the children can be created on demand when needed in your control's life cycle. This is especially important when you create a composite control whose child controls handle postback data. To ensure that child controls are created before code tries to access them, the Control class defines the protected EnsureChildControls method. This method checks whether the child controls have been created and invokes the CreateChildControls method to create child controls only if they have not been created. Any code in your control's implementation that needs to access a child control must first invoke the EnsureChildControls method. For example, the default implementation of the FindControl method, which the page uses to locate a child control, first invokes the EnsureChildControls method. Note that if child controls have not been created in your control's life cycle prior to the PreRender phase, they are created on demand at this point. This is because the default implementation of the PreRender method invokes the EnsureChildControls method of all controls whose Visible property is true . Let's now examine why you must implement the INamingContainer interface. INamingContainer is a marker interface that does not have any methods but causes the page to create a new naming scope under your control. When you implement this interface, any child controls that your control contains are guaranteed to have identifiers (represented by the UniqueID property) that are truly unique on the page. For example, if a page developer placed two instances of your composite control on a page, the child controls within the first instance would have different unique identifiers from those within the second instance, even though both sets of child controls have the same ID property values. This is especially important if the page needs to find a control to route postback data or route a postback event to it. We will describe the UniqueID property in more detail at the end of the next section.
|