WSS introduces a powerful new extensibility mechanism known as delegate controls. In some ways, a delegate control is similar to a named placeholder because it defines a region inside a master page that can be substituted with unique content to meet the needs of a particular business solution. Like a placeholder, a delegate control can optionally supply default content that is used until a substitution is performed.
One major difference when compared to placeholders is that the substitution mechanism for replacing the contents of a delegate control is driven through feature activation. Therefore, you can replace what’s defined inside a delegate control in default.master without requiring any changes to default.master or the site pages that link to it. All you need to do is define a Control element within a feature and then activate that feature.
A significant aspect of using delegate controls involves the scope of the feature that is being used to drive substitution. When you design a feature to substitute the contents of a delegate control, your feature can be scoped at any of the four supported levels. These levels include site scope, site collection scope, Web application scope, and farm scope. This dimension of delegate controls provides a powerful mechanism for enabling and disabling functionality on a wide-scale basis.
Let’s begin by looking at an example of a delegate control that is defined in default.master to create the region that defines the standard search area in site pages just above the Site Settings menu. The delegate control definition in default.master looks like the following:
This is an example of a delegate control that defines no default content. Instead, the default content for this delegate control is supplied by a standard WSS feature named ContentLightup. The ContentLightup feature defines a Control element that substitutes content into the SmallSearchInputBox delegate control by referencing a built-in user control with the standard WSS search area content.
If you want to replace a delegate control, such as the WSS search area, with your own customized version, you start by adding a Control element to a feature. The Control element should have an ID value of SmallSearchInputBox. The Control element should also have a Sequence number smaller than any other active Control element pointing to the same ID. The following code demonstrates how the Control element is defined inside the elements.xml file of the CustomBranding feature.
In addition to substituting delegate controls by using .ascx files, WSS also supports delegate control substitution by using control classes that are compiled into assemblies installed in the Global Assembly Cache. As an example, let’s examine a technique for replacing the SiteMapDataSource that is used to populate the Quick Launch menu. Examine the following fragment from the standard default.master page template that defines a delegate control named QuickLaunchDataSource.
Unlike the last example of a delegate control, this delegate control with a ControlId of QuickLaunchDataSource defines default content that is used until a substitution is performed. The default content includes a SiteMapDataSource control with an ID of QuickLaunchSiteMap. If you want to substitute this control with a different SiteMapDataSource control, you can add the following Control element to a custom feature.
QuickLaunchSiteMap SPSiteMapProvider False
As shown in the previous example, this Control element provides an ID that matches the ControlId of the target delegate on which the substitution should be performed. However, this example differs because it uses the ControlAssembly and ControlClass attributes to reference a specific control type within a target assembly.
You should also observe that the Control element contains several nested Property elements that define the initialization parameters for the control instance being used in the substitution. It is important in this example that the control instance being created is assigned an ID of QuickLaunchSiteMap because the hosting page expects to find a control of that name. The control instance is also initialized to use the SPSiteMapProvider class, which provides different behavior than the default that uses the SPNavigationProvider class instead.