Create a Custom Action with Code

A few months ago when I was writing the SharePoint 2010 for Developers course for AppDev I noticed an important difference in the behavior of CustomAction between sandbox and farm deployment – something I personally think is a bug. When you deploy a CustomAction to the sandbox, you can target a specific list instance by using a token in the RegistrationId attribute as so:

RegistrationId="{$ListId:Lists/MyList;}"

SharePoint replaces the token at activation time with the list’s actual ID. This doesn’t work if you deploy the feature as part of a farm solution. In SharePoint 2010 you can use the same token syntax for the List attribute in a Field feature element to create a Lookup field with a feature without writing code in both farm or sandbox mode.

Because of this inconsistency, if you need to create a ribbon button that applies to a specific list in a farm deployment scenario you must write some code in a feature event receiver to create an SPUserCustomAction class as so:

SPList list = web.Lists["SomeList"];
SPUserCustomAction action = list.UserCustomActions.Add();
action.Title = "Do Something";
action.Description = "Sample ribbon button";
action.ImageUrl = "/_layouts/images/centraladmin_backupandrestore_granularbackup_32x32.png";
action.Location = "CommandUI.Ribbon.ListView";
action.Sequence = 0;
action.Url = "javascript:DoAction();";
action.CommandUIExtension =
@"<CommandUIExtension xmlns='http://schemas.microsoft.com/sharepoint/'>
<CommandUIDefinitions>
<CommandUIDefinition Location='Ribbon.Documents.Manage.Controls._children'>
<Button Id='Sample.DoSomething.Button'
Command='Sample.DoSomething'
Image32by32='/_layouts/images/centraladmin_backupandrestore_granularbackup_32x32.png'
Image16by16='/_layouts/images/centraladmin_backupandrestore_granularbackup_32x32.png'
Sequence='0'
LabelText='Do Something'
Description='Sample ribbon button'
TemplateAlias='o1' />
</CommandUIDefinition>
</CommandUIDefinitions>
<CommandUIHandlers>
<CommandUIHandler Command='Sample.DoSomething'
CommandAction='javascript:DoAction();'
EnabledScript='javascript:EnableDoAction();'/>
</CommandUIHandlers>
</CommandUIExtension>"
;

action.Update();

 

The association with the list isn’t done by setting the RegistrationId or RegistrationType properties, but rather by adding the custom action to the SPList’s UserCustomActions collection and you’ll get an error if you try to set these properties in the context of an action for SPList. However, both SPSite and SPWeb expose UserCustomActions collection properties and you can use these to programmatically create other custom actions where RegistrationId and RegistrationType apply.

Author: Doug Ware