Walkthrough: Creating a Custom Web Part with a Contextual Tab

Applies to: SharePoint Foundation 2010

This topic shows how to create a custom Web Part that opens a contextual tab on the Server ribbon in Microsoft SharePoint Foundation.

Prerequisites

Microsoft SharePoint Foundation 2010

SharePoint development tools in Microsoft Visual Studio 2010

Creating a SharePoint Project

To create the Web Part and ribbon customization, start by creating an empty SharePoint project.

To create a SharePoint Project

  1. Start Visual Studio 2010.

  2. On the File menu, point to New, and then click Project.

  3. In Project Types, under C#, select Empty SharePoint Project.

  4. Type ContextualTabWebPart as the project name, and then click OK.

  5. In the SharePoint Customization Wizard, select Deploy as a farm solution, and then click Finish.

Implementing the Web Part

Now, you implement the Web Part.

To implement the Web Part

  1. In Solution Explorer, right-click References, and then select Add Reference.

  2. In the Add Reference dialog box, select the .NET tab, and then select Microsoft.Web.CommandUI.dll. Click OK.

  3. In Solution Explorer, right-click the ContextualTabWebPart project, point to Add, and then select New Item.

  4. In the Add New Item dialog box, select Web Part. Type ContextualTabWebPart as the name.

  5. After the Web Part is added and the ContextualTabWebPart.cs file is shown, add the following statements.

    using System.Xml;
    using Microsoft.Web.CommandUI;
    
  6. Next, implement the IWebPartPageComponentProvider interface as shown in the following code. You will work with this later.

    public class ContextualTabWebPart : WebPart, IWebPartPageComponentProvider
    

    Next, you create two global string variables for the ribbon XML. These two variables define the contextual tab and the group templates. For more information about the ribbon XML, see Server Ribbon XML.

  7. In the contextualTab string, notice the ContextualGroup element. This element defines the following Tab element as a contextual tab. The Color attribute defines the color of the tab when it renders. The Id and ContextualGroupId are unique identifiers for the group. The Sequence attribute defines where the contextual tab will render. The following code implements the two global string variables.

    private string contextualTab = @"
       <ContextualGroup Color=""Magenta"" 
         Command=""CustomContextualTab.EnableContextualGroup"" 
         Id=""Ribbon.CustomContextualTabGroup"" 
         Title=""Custom Contextual Tab Group"" 
         Sequence=""502"" 
         ContextualGroupId=""CustomContextualTabGroup"">
              <Tab 
                  Id=""Ribbon.CustomTabExample"" 
                  Title=""My Custom Tab"" 
                  Description=""This holds my custom commands!"" 
                  Command=""CustomContextualTab.EnableCustomTab"" 
                  Sequence=""501"">
                <Scaling
                  Id=""Ribbon.CustomTabExample.Scaling"">
                  <MaxSize
                    Id=""Ribbon.CustomTabExample.MaxSize"" 
                    GroupId=""Ribbon.CustomTabExample.CustomGroupExample"" 
                    Size=""OneLargeTwoMedium""/>
                  <Scale 
                    Id=""Ribbon.CustomTabExample.Scaling.CustomTabScaling""
                    GroupId=""Ribbon.CustomTabExample.CustomGroupExample"" 
                    Size=""OneLargeTwoMedium"" />
                </Scaling>
                <Groups Id=""Ribbon.CustomTabExample.Groups"">
                  <Group 
                    Id=""Ribbon.CustomTabExample.CustomGroupExample"" 
                    Description=""This is a custom group!"" 
                    Title=""Custom Group"" 
                    Command=""CustomContextualTab.EnableCustomGroup"" 
                    Sequence=""52"" 
                    Template=""Ribbon.Templates.CustomTemplateExample"">
                    <Controls 
                      Id=""Ribbon.CustomTabExample.CustomGroupExample.Controls"">
                      <Button 
                        Id=""Ribbon.CustomTabExample.CustomGroupExample.HelloWorld"" 
                        Command=""CustomContextualTab.HelloWorldCommand"" 
                        Sequence=""15"" 
                        Description=""Says hello to the World!"" 
                        LabelText=""Hello, World!"" 
                        TemplateAlias=""cust1""/>
                      <Button 
                        Id=""Ribbon.CustomTabExample.CustomGroupExample.GoodbyeWorld"" 
                        Command=""CustomContextualTab.GoodbyeWorldCommand"" 
                        Sequence=""17"" 
                        Description=""Says good-bye to the World!"" 
                        LabelText=""Good-bye, World!"" 
                        TemplateAlias=""cust2""/>
                    </Controls>
                  </Group>
                </Groups>
              </Tab>
       </ContextualGroup>";
     
            private string contextualTabTemplate = @"
              <GroupTemplate Id=""Ribbon.Templates.CustomTemplateExample"">
                <Layout 
                  Title=""OneLargeTwoMedium"" LayoutTitle=""OneLargeTwoMedium"">
                  <Section Alignment=""Top"" Type=""OneRow"">
                    <Row>
                      <ControlRef DisplayMode=""Large"" TemplateAlias=""cust1"" />
                    </Row>
                  </Section>
                  <Section Alignment=""Top"" Type=""TwoRow"">
                    <Row>
                      <ControlRef DisplayMode=""Medium"" TemplateAlias=""cust2"" />
                    </Row>
                    <Row>
                      <ControlRef DisplayMode=""Medium"" TemplateAlias=""cust3"" />
                    </Row>
                  </Section>
                </Layout>
              </GroupTemplate>";
    
  8. Create a new string property named DelayScript. DelayScript contains ECMAScript (JavaScript, JScript) that adds and registers your custom page component. You create the custom page component later in this topic. The _addCustomPageComponent method creates the custom page component and adds it to the page manager. Every Web Part has a page component, and you will use the Web Part's page component id when you create a custom page component object. This is necessary to associate the Web Part with the page component to enable contextually switching to your custom ribbon tab. The _registerCustomPageComponent method registers your JavaScript file when the page loads.

    The following code implements DelayScript.

            public string DelayScript 
            {
                get
                {
                    string webPartPageComponentId = SPRibbon.GetWebPartPageComponentId(this);
                    return @"
    <script type=""text/javascript"">
    //<![CDATA[
     
                function _addCustomPageComponent()
                {
                    var _customPageComponent = new ContextualTabWebPart.CustomPageComponent('" + webPartPageComponentId + @"');
                    SP.Ribbon.PageManager.get_instance().addPageComponent(_customPageComponent);
                }
     
                function _registerCustomPageComponent()
                {
                    SP.SOD.registerSod(""CustomContextualTabPageComponent.js"", ""\/_layouts\/CustomContextualTabPageComponent.js"");
                    SP.SOD.executeFunc(""CustomContextualTabPageComponent.js"", ""ContextualWebPart.CustomPageComponent"", _addCustomPageComponent);
                }
                SP.SOD.executeOrDelayUntilScriptLoaded(_registerCustomPageComponent, ""sp.ribbon.js"");
    //]]>
    </script>";
                }
            }
    
  9. Create a new function called AddContextualTab. Inside the AddContextualTab method, you will insert code to register the contextual tab and custom templates with the ribbon. The RegisterDataExtension(XmlNode, String) method is used to register the ribbon extensions. RegisterDataExtension(XmlNode, String) tells the ribbon where to load the XML that is passed into it. You use the ids of the ContextualTabs and Templates elements in CMDUI.xml.

    The following code implements the AddContextualTab method.

            private void AddContextualTab()
            {
     
                // Get the current instance of the ribbon on the page.
                Microsoft.Web.CommandUI.Ribbon ribbon = SPRibbon.GetCurrent(this.Page);
     
                // Prepare an XmlDocument object used to load the ribbon extensions.
                XmlDocument ribbonExtensions = new XmlDocument();
     
                // Load the contextual tab XML and register the ribbon extension.
                ribbonExtensions.LoadXml(this.contextualTab);
                ribbon.RegisterDataExtension(ribbonExtensions.FirstChild, "Ribbon.ContextualTabs._children");
     
                // Load the custom templates and register the ribbon extension.
                ribbonExtensions.LoadXml(this.contextualTabTemplate);
                ribbon.RegisterDataExtension(ribbonExtensions.FirstChild, "Ribbon.Templates._children");
            }
    
  10. Now, you must implement the WebPartContextualInfo property of the IWebPartPageComponentProvider interface. To implement the interface, right-click IWebPartPageComponentProvider, and select Implement Interface, and then select Implement Interface Explicitly.

    This interface lets the ribbon know when a Web Part is selected and which contextual group and tab to show. When you add the contextual group, you send it the id of the contextual group, the VisibilityContext, and the Command. The id maps to the Id property of the ContextualGroup element in the ribbon XML. The VisibilityContext is used to group controls in order to show or hide them. The Command parameter maps to the Command of the ContextualGroup element in the ribbon XML. You also add the tab that was defined in the ribbon XML. You must pass in only the Id and the VisibilityContext parameters for the tab. Insert the following code for the WebPartContextualInfo.

            public WebPartContextualInfo WebPartContextualInfo
            {
                get 
                {
                    WebPartContextualInfo info = new WebPartContextualInfo();
                    WebPartRibbonContextualGroup contextualGroup = new WebPartRibbonContextualGroup();
                    WebPartRibbonTab ribbonTab = new WebPartRibbonTab();
     
                    // Create the contextual group object and initialize its values.
                    contextualGroup.Id = "Ribbon.CustomContextualTabGroup";
                    contextualGroup.Command = "CustomContextualTab.EnableContextualGroup";
                    contextualGroup.VisibilityContext = "CustomContextualTab.CustomVisibilityContext";
     
                    // Create the tab object and initialize its values.
                    ribbonTab.Id = "Ribbon.CustomTabExample";
                    ribbonTab.VisibilityContext = "CustomContextualTab.CustomVisibilityContext";
     
                    // Add the contextual group and tab to the WebPartContextualInfo.
                    info.ContextualGroups.Add(contextualGroup);
                    info.Tabs.Add(ribbonTab);
                    info.PageComponentId = SPRibbon.GetWebPartPageComponentId(this);
     
                    return info;
                }
            }
    
  11. Next, you implement the OnPreRender method. This enables you to add elements to the ribbon before it is rendered on the page. Inside OnPreRender, you call the AddContextualTab method and register the DelayScript with the ClientScriptManager.

    The following code implements the OnPreRender method.

            protected override void OnPreRender(EventArgs e)
            {
                base.OnPreRender(e);
     
                this.AddContextualTab();
     
                ClientScriptManager clientScript = this.Page.ClientScript;
                clientScript.RegisterClientScriptBlock(this.GetType(), "ContextualTabWebPart", this.DelayScript);
     
            }
    

    The Web Part is finished. Next, you create the page component.

Creating the Page Component

A page component is an JavaScript object that is used to interact with the Server ribbon. For an in-depth walkthrough of the page component, see Developing Page Components for the Server Ribbon. For the page component to operate correctly, you have to deploy it by using a module to the %ProgramFiles%\Common Files\Microsoft Shared\web server extensions\14\\TEMPLATES\LAYOUTS directory. It enables commands on the ribbon and responds to the commands that you define in the ribbon XML.

To add and define the page component

  1. In Solution Explorer, right-click the ContextualTabWebPart project, point to Add, and then select New Item.

  2. In the Add New Item dialog box, select the Module template, and type CustomContextualTabPageComponent as the name. Click Add.

  3. You do not need the default files that are added. In Solution Explorer, delete Elements.xml and Sample.txt.

  4. Now, you must add the JavaScript file. Right-click CustomContextualTabPageComponent, point to Add, and then select New Item.

  5. In the Installed Templates list, under Visual C#, select Web. Select the Jscript File type, and type CustomContextualTabPageComponent as the name.

  6. You must set the deployment location to make sure that the file goes into the _layouts directory. To do this, in Solution Explorer, select CustomContextualTabPageComponent.js. In the Properties window, set the Deployment Type to Root File. Open the Deployment Location property, and type TEMPLATE\LAYOUTS in the Path property.

    Add the following code in the CustomContextualTabPageComponent.js file to implement your custom page component.

    Type.registerNamespace('ContextualTabWebPart');
     
    var _webPartPageComponentId;
    ContextualTabWebPart.CustomPageComponent = function ContextualTabWebPart_CustomPageComponent(webPartPcId) {
        this._webPartPageComponentId = webPartPcId;
        ContextualTabWebPart.CustomPageComponent.initializeBase(this);
    }
    ContextualTabWebPart.CustomPageComponent.prototype = {
     
        init: function ContextualTabWebPart_CustomPageComponent$init() {  },
     
        getFocusedCommands: function ContextualTabWebPart_CustomPageComponent$getFocusedCommands() {
            return ['CustomContextualTab.EnableCustomTab', 'CustomContextualTab.EnableCustomGroup', 'CustomContextualTab.HelloWorldCommand', 'CustomContextualTab.GoodbyeWorldCommand'];
        },
     
        getGlobalCommands: function ContextualTabWebPart_CustomPageComponent$getGlobalCommands() {
            return [];
        },
     
        isFocusable: function ContextualTabWebPart_CustomPageComponent$isFocusable() {
            return true;
        },
        
        canHandleCommand: function ContextualTabWebPart_CustomPageComponent$canHandleCommand(commandId) {
            // Contextual Tab commands
            if ((commandId === 'CustomContextualTab.EnableCustomTab') || (commandId === 'CustomContextualTab.EnableCustomGroup') || (commandId === 'CustomContextualTab.HelloWorldCommand') || (commandId === 'CustomContextualTab.GoodbyeWorldCommand')) {
                return true;
            }
        },
     
        handleCommand: function ContextualTabWebPart_CustomPageComponent$handleCommand(commandId, properties, sequence) {
     
            if (commandId === 'CustomContextualTab.HelloWorldCommand') {
                alert('Hello, world!');
            }
            if (commandId === 'CustomContextualTab.GoodbyeWorldCommand') {
                alert('Good-bye, world!');
            }
        },
     
        getId: function ContextualTabWebPart_CustomPageComponent$getId() {
            return this._webPartPageComponentId;
        }
    }
     
     
    ContextualTabWebPart.CustomPageComponent.registerClass('ContextualTabWebPart.CustomPageComponent', CUI.Page.PageComponent);
    SP.SOD.notifyScriptLoadedAndExecuteWaitingJobs("CustomContextualTabPageComponent.js");
    

Deploying the Customization

The project is deployed automatically by the SharePoint development tools in Visual Studio 2010. The application pool is automatically reset as part of the deployment process.

To deploy the Web Part

  1. Press F5. The SharePoint development tools in Visual Studio 2010 automatically build and deploy the Web Part and JavaScript file.

  2. Navigate to your site.

  3. Click the Edit button.

  4. On the Insert tab, click the Web Part button.

  5. In the Web Part Adder, select the Custom category.

  6. In the list of Web Parts, select ContextualTabWebPart, and then click Add.

  7. After the Web Part is added to the page, click the ContextualTabWebPart Web Part.

  8. Notice the Custom Contextual Tab Group tab that appears.

See Also

Concepts

Server Ribbon XML

Developing Page Components for the Server Ribbon

Imperative Customization of the Server Ribbon

Declarative Customization of the Server Ribbon