SharePoint 2010 + Document Sets + Custom Ribbon Buttons with Custom Code

Thu, Oct 27, 2011 4-minute read

I recently posted a guide on how to add an item to the SharePoint 2010 context menu (“EditControlBlock”) and run some custom code on the click action. SharePoint 2010 uses the love-it-or-hate-it Microsoft Ribbon, which, to the developer, is fully accessible. This guide will show you how to implement a custom button for a Document Set, in the Manage group and also on the Edit form, and run some custom code when it’s clicked, in Visual Studio 2010.

There are three components you need to do this:

  • Your ribbon buttons
  • A delegate action that ties up your buttons to your
  • Custom code that should run

I’ll quickly skim through the process.

  1. Create a new empty SharePoint 2010 project, Deploy as a Farm Solution
  2. Note: if you change the name of your project, which you likely will, then the default namespace of your project will change to the project name. In this example, my project is called SharePointProject1, so I have a namespace of SharePointProject1. Therefore, whereever you see SharePointProject1, you should replace it with the namespace of your project.
  3. Right click the project and add a New Empty Element, call it RibbonButton
  4. In your empty element, create the code for your button Version 1: a button in the Manage group in the main ribbon, which appears when you’re looking at a document set.
<elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <customaction Location="CommandUI.Ribbon" RegistrationId="0x0120D520" RegistrationType="ContentType" Title="Custom Document Set Button" Id="Ribbon.Documents.DocsetButton">
    <commanduiextension>
      <commanduidefinitions>
        <commanduidefinition Location="Ribbon.ManageDocumentSet.MDS.Manage.Controls._children">
          <button Id="Ribbon.ManageDocumentSet.MDS.Manage.Controls.CustomButton" TemplateAlias="o1" ToolTipDescription="Demonstrate a ribbon doing something cool" ToolTipTitle="Download as Zip" LabelText="Weeeee" Image32by32="/_layouts/images/zipfile32x.png" Image16by16="/_layouts/images/zipfile16x.png" Alt="Weee" Command="Ribbon.ManageDocumentSet.MDS.Manage.CustomButtonClick" Sequence="20"></button>
        </commanduidefinition>
      </commanduidefinitions>
      <commanduihandlers>
        <commanduihandler Command="Ribbon.ManageDocumentSet.MDS.Manage.CustomButtonClick" CommandAction="javascript:__doPostBack('MyDelegateEvent', '')"></commanduihandler>
      </commanduihandlers>
    </commanduiextension>
  </customaction>
</elements>

or alternatively, to add a button to the Document Set edit form:

<elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <customaction Location="CommandUI.Ribbon.EditForm" RegistrationId="0x0120D520" RegistrationType="ContentType" Title="Custom Document Set Button" Id="Ribbon.Documents.DocsetButton">
    <commanduiextension>
      <commanduidefinitions>
        <commanduidefinition Location="Ribbon.DocLibListForm.Edit.Actions.Controls._children">
          <button Id="Ribbon.ManageDocumentSet.MDS.Manage.Controls.CustomButton" TemplateAlias="o2" ToolTipDescription="Demonstrate a ribbon doing something cool" ToolTipTitle="Download as Zip" LabelText="Weeeee" Image32by32="/_layouts/images/zipfile32x.png" Image16by16="/_layouts/images/zipfile16x.png" Alt="Weee" Command="Ribbon.ManageDocumentSet.MDS.Manage.CustomButtonClick" Sequence="20"></button>
        </commanduidefinition>
      </commanduidefinitions>
      <commanduihandlers>
        <commanduihandler Command="Ribbon.ManageDocumentSet.MDS.Manage.CustomButtonClick" CommandAction="javascript:__doPostBack('MyDelegateEvent', '')"></commanduihandler>
      </commanduihandlers>
    </commanduiextension>
  </customaction>
</elements>
  1. A couple of things to say about the above. The Command attribute of the Button element should be the same as the Command attribute of the CommandUIHandler element. This is what ties the two together. Secondly: the templateAlias attribute is annoyingly important! I found that if you have it set incorrectly, then the button won’t display at all. According to the docs, “o1” is to display a large image, whereas “o2” is to display a small image. However, it seems that the main ribbon only supports “o1” and the EditForm ribbin only supports “o2”.
  2. For a full list of locations that you may want to add buttons, view this page: http://msdn.microsoft.com/en-us/library/ee537543.aspx
  3. Now, add a Class file to your project, called “MyClass”
  4. The guts of the class should look like this:
using System.IO;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using System.Web.UI.WebControls;

namespace SharePointProject1
{
    public class MyClass : WebControl
    {
        const string MYEVENT = "MyDelegateEvent";

        protected override void OnLoad(EventArgs e)
        {
            this.EnsureChildControls();
            base.OnLoad(e);
            if (this.Page.Request["__EVENTTARGET"] == MYEVENT)
            {
// custom code here
                int itemId = Convert.ToInt32(this.Page.Request["__EVENTARGUMENT"]);
                System.IO.TextWriter mywriterFired = new StreamWriter(@"C:\zzz_CodeBehindFileItemMenu.txt", true);
                mywriterFired.WriteLine("Event Fired at:" + DateTime.Now.ToLongTimeString() + ": Item ID:" + itemId.ToString());
                mywriterFired.Close();
            }
        }

    }
}

I’m just reusing the code in my previous example, which writes out a text file, but this where you can do whatever you want with your custom code.

  1. Now, build the project, and then Deploy.
  2. Head to C:Windowsassembly, find the SharePointProject1 .dll and note down the PublicKeyToken in its properties.
  3. Now update your web.config to add a SafeControls entry:
<safecontrol Assembly="SharePointProject1", Version=1.0.0.0, Culture=neutral, PublicKeyToken={token}" Namespace="SharePointProject1" TypeName="*" Safe="True"></safecontrol>
  1. Now, back in your project, add a second Empty Element to your project called RibbonButtonDelegate
  2. Update the Elements.xml file to look like this:
<elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <control ControlClass="SharePointProject1.MyClass" 
    ControlAssembly="SharePointProject1, Version=1.0.0.0, Culture=neutral, PublicKeyToken={token}" 
    Sequence="50" Id="AdditionalPageHead"></control>
</elements>

Replacing {token} with the token you noted down.

  1. Add a feature to your project. Open the feature and ensure both of your Elements are in the feature. Set the scope to Web.
  2. Deploy your project (right click the Project > Deploy.)
  3. Restart IIS
  4. Navigate to a Document Library which has Document Sets enabled, and browse in to Document Set. Depending on which button you created (or both) you should now see a new button in the Manage group or in the Edit Properties form.
  5. Click the button, and your code should run.

Happy days.