Delegate Controls – Why you need to delegate!

I wanted to introduce this topic before my break for the festive season, as I am going to be offline pretty much until a few weeks into 2009. And this topic is around the subject of Delegate Controls!

What are Delegate Controls?
Well .. delegates are basically a new control that can be used in SharePoint (both WSS 3.0 and MOSS 2007) which allow you to render different controls on different sites, using features to switch them on and off.

Sound interesting? Well let me whet your appetite further.

Apart from the fact that you can create your own delegates (hopefully your dev brain boggles already!) but Delegates are already in use in a large number of places in SharePoint:

  • Top Navigation Menu Control
  • Quick Launch Menu Control
  • Search Controls
  • My Links / Quick Links controls
  • etc …

So .. in short, if you want to modify these controls you don’t need to modify the master page.
I’ll say that again, just in case you missed it. You don’t need to modify the master page.

The delegate controls are already in the default.master, so you just need to install and activate a feature which tells SharePoint to use your custom control instead of the standard ones!

Neat huh? (I knew you’d like it)

So what kind of controls can I use with Delegates?
You’ll like this answer too …. anything.

Yep, any control (either ASCX based user controls, or DLL based server controls) can be dropped into a delegate. All you need is a feature that registers it!

So how does it all work then?
Well .. delegates have 2 parts to them:

  • ASP.Net Delegate Control (effectively a placeholder)
  • Feature which registers a new ASP.Net control to use in place of the delegate

The structure of a Delegate Control is very simple:

<SharePoint:DelegateControl runat="server" ControlId="SmallSearchInputBox" />

You only have 1 attribute to worry about; ControlId is basically a unique "name" for your placeholder. The example shown here is for the standard Search control that appears on every page.

After you’ve got your Delegate Control, you need a feature to implement your actual ASP.Net controls. Luckily the feature is quite straightforward.

Example using Server Control
<?xml version="1.0" encoding="utf-8" ?>
<Elements xmlns="https://schemas.microsoft.com/sharepoint/">
    <Control
        Id="SmallSearchInputBox"
        Sequence="25"
        ControlClass="Microsoft.SharePoint.Portal.WebControls.SearchBoxEx"
        ControlAssembly="Microsoft.SharePoint.Portal, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c">
            <Property Name="GoImageUrl">/_layouts/images/gosearch.gif</Property>
            <Property Name="GoImageUrlRTL">/_layouts/images/goRTL.gif</Property>
            <Property Name="GoImageActiveUrl">/_layouts/images/gosearch.gif</Property>
            <Property Name="GoImageActiveUrlRTL">/_layouts/images/goRTL.gif</Property>
            <Property Name="UseSiteDefaults">true</Property>
            <Property Name="FrameType">None</Property>
            <Property Name="ShowAdvancedSearch">true</Property>
    </Control>   
</Elements>
 
Example using User Control
<?xml version="1.0" encoding="utf-8" ?>
<Elements xmlns="https://schemas.microsoft.com/sharepoint/"> 
    <Control Id="CentralAdminLeftNavBarTop" Sequence="100" ControlSrc="~/_admin/configurationmonitor.ascx" />
</Elements>

The Id is the same as your "ControlId" property in your Delegate control. Then you either reference a set of Control Class / Control Assembly, or you point it to a relative path to the ASCX control using the ControlSrc property.

Thats it! Once your feature is activated (at whatever scope you choose … Farm, Application, Site, Web) then your ASP.Net control will appear in place of the delegate!

But what about Sequence??
Ahhh … well that is where the real beauty of Delegates comes through in a SharePoint environment! As the controls are installed and activated using Features, how do you account for having multiple features at multiple scopes?

The Sequence attribute allows you to offer a number value which will be used when choosing which feature has priority. Simply put, the feature with the lowest sequence number will be rendered.

This allows you to achieve 2 different things:

  1. Upgrade Path
  2. Different controls on different sites

In the example of an Upgrade path, take the example of the "SmallSearchInputBox" ControlId.

In WSS 3.0 this is implemented through a feature with a Sequence of 100. In MOSS 2007 Standard a replacement control was installed with a Sequence of 50. And in MOSS 2007 Enterprise another new control is implemented with a Sequence of 25!

Hopefully you can see the picture, but I’ll join the dots anyway!

The same delegate, and the same master page is used in all 3 installs. But as you install a newer version, a replacement feature is activated (with a lower sequence number) which takes preference.

So .. if you wanted to replace the "SmallSearchInputBox" control in a WSS 3.0 system, but wanted the "out of the box" control to come back if they ever install MOSS 2007, then you could register your own feature with a Sequence of anything between 100 and 50.

This same approach can be used if you wanted to replace controls on a specific site. So lets say you want to replace the Quick Launch navigation control in specific web sites. You could create a Web scoped feature, and activate it on those sites that you want to replace the Quick Launch in.

No Master Page, No ASP.Net Web Form dev … easy.