DCSIMG
Fun with Silverlight and SharePoint 2010 Ribbon Control - Part 2 - An In Depth Look At The Ribbon Control - Johnny's RIA Corner

Fun with Silverlight and SharePoint 2010 Ribbon Control - Part 2 - An In Depth Look At The Ribbon Control

Welcome to part 2 of the "Fun with Silverlight and SharePoint 2010 Ribbon Control" series. If you haven't read part 1 go ahead and click here.

So how do we deal with this ribbon? Well, by using the powers of XML!

Let's take a closer look on how the OOTB ribbon is constructed:
If we open the ribbon definitions file - cmdui.xml (which can be found at C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\GLOBAL\XML) we will see the following structure:

<?xml version="1.0" encoding="utf-8"?>
<
CommandUI xmlns="http://schemas.microsoft.com/sharepoint/">
<
Ribbon Id="Ribbon" ...>
    <Tabs Id="Ribbon.Tabs">
        <
Tab Id="Ribbon.BDCAdmin" ...>
            <
Scaling Id="Ribbon.BDCAdmin.Scaling"></Scaling>
            <
Groups Id="Ribbon.BDCAdmin.Groups">
                <
Group Id="" ...>
                    <
Controls Id="">
                        <
Button Id="" .../>
                    </
Controls>
                </
Group>
            </
Groups>
        </
Tab>
    </
Tabs>
</
Ribbon>

The first thing that should pop out to your eyes is how this xml has a clear and simple hierarchy: Ribbon -> Tab -> Group -> Controls.

A site can have one and only one ribbon control (it wouldn't really make any sense to have two, would it?) but could have many tabs or groups and of course controls.

Now that's all fun and stuff but when can we put our Silverlight control inside this ribbon?! Well, you'll have to hold your horses a bit longer and follow these instructions:

1) Look at our SharePoint project; there is an item called "RibbonElement". This is just an empty xml element that we will use for our ribbon customization.

2) The first element we need to add to our xml is the CustomAction element. This element tells SharePoint how to register our element by specifying the scope and location of it.
Add the following code to your Element.xml file right after the xml declaration:

<CustomAction Id="Ribbon.SilverlightExample" RegistrationType="List" RegistrationId="101" Location="CommandUI.Ribbon">
</
CustomAction>

Attributes In Focus:
  • Id - The id of the element. Can be anything you like.
  • RegistrationType and RegistrationId - defines the scope of our element. In our example we use the scope of a list of type Document Library (101). RegistrationId is basically the template id of the list type you wish to use (you can find a nice list of those ids here).
  • Location - should always be "CommandUI.Ribbon".

3) Next we have the CommandUIExtention and CommandUIDefenitions elements. Add them between the CustomAction starting and closing elements:

<CommandUIExtension>
    <
CommandUIDefinitions>
    </CommandUIDefinitions>
</CommandUIExtension>
 

4) Now we need to add the CommandUIDefinition tag, which define where to render our new tab. The location attribute (which is mandatory of course) tells SharePoint to render the tab as a child of the Tabs collection or the ContextualTabs collection.
ContextualTabs will be discussed in a later part of this series and for now we will add our new tab to the Tabs collection.

<CommandUIDefinition Location="Ribbon.Tabs._children">
</CommandUIDefinition>

5) Once you have a commandUIDefinition element you can add a new custom tab to it.
Add the following tab element to your code between the CommandUIDefinition starting and closing elements:

<Tab Id="Ribbon.SilverlightExample" Sequence="501" Description="My New Silverlight control Tab" Title="My Silverlight Tab">
</
Tab>

 Attributes In Focus:

  • Id - The id of the tab. Like before, can be anything you like.
  • Sequence - The Sequence attribute defines where our new tab will render in regards to other tabs. Default OOTB tabs has a sequence value in multiplies of 100 (100,200,300 etc.) so our custom one should not be a multiple of 100 to prevent collisions with OOTB tabs.
  • Title and Description - The title and Description of our tab.

6) Next we need to define the scaling of the tab using the Scaling elements.
Each group of controls (more on this later) needs one MaxSize and one Scale element to define how the controls inside of it will behave when the browser is either in full size mode (MaxSize) or resized (Scale).
If we define elements for more than one group, we define MaxSize first (so if we have two groups, we will have two MaxSize elements, one after another) and then Scale.
Type the following code between the Tab opening and closing elements.

<Scaling Id="Ribbon.SilverlightExample.scaling">
    <
MaxSize Id="Ribbon.SilverlightExample.scaling.MaxSize" GroupId="Ribbon.SilverlightExample.GalleryGroup" Size="OneLarge"/>
    <
Scale Id="Ribbon.SilverlightExample.scaling.customScaling" GroupId="Ribbon.SilverlightExample.GalleryGroup" Size="OneLarge"/>
</
Scaling>

 Attributes In Focus:

  • GroupId - This attribute associate a group to this scaling. As previous mentioned each group we define needs its own MaxSize and Scale elements and by using the GroupId we tell SharePoint which elements belongs to which group.
  • Size - The name of the layout that defines this element. We will use this value later when we get to group templates.

7) Once we are done with the Scaling, we need some groups to scale don’t we?

  • The Groups element contains a collection of Group elements and its purpose is to define the groups that will appear on a tab.
  • Group is a container for controls. In the image below "Edit" is a group, "Manager" is a group, "Share & Track" is a group and of course "Page Actions" is a group.
    All of these groups are contained inside a single Groups element.

Type the following code right after the closing Scaling element:

<Groups Id="Ribbon.SilverlightExample.Groups">
    <
Group Id="Ribbon.SilverlightExample.GalleryGroup" Description="This is the Silverlight control group" Title="Silverlight Control Group"
       
Sequence="52" Template="Ribbon.Templates.SilverlightExampleTemplate">
   
</Group>
</
Groups>

 Attributes In Focus:

  • Title - The name of the group that will be shown to the user (like Edit or Manage in the picture above).
  • Sequence - Same as the sequence of the Tab element, but this time the OOTB sequence numbers are multiples of 10 and not 100. Again we won't use numbers in multiples of 10 when we develop a custom tab.
  • Template - The name of the template that defines the layout of the controls inside of the group. We will define it later on when we deal with templates.

8) Before we can add any control to our new group we need to add an element that represent a collection of controls. Type the following code between the opening and closing Group element:

<Controls Id="Ribbon.SilverlightExample.Controls">
</
Controls>

9) Now for the fun part! There is a limited number of predefined controls that we can add to a ribbon control: Button,Checkbox,DropDownList etc.
Since we want to add a Silverlight application we must have an object tag that will render it, so we need a control that let us write our own HTML code, and the only ribbon control that has an attribute for that is the GalleryButton.
Add the following code between the opening and closing Controls element: 

<GalleryButton TemplateAlias="control1" Id="SilverlightControl" InnerHTML="&lt;div id='silverlightControlHost'&gt;&lt;object data='data:application/x-silverlight-2,' type='application/x-silverlight-2' width='190px' height='60px'&gt;&lt;param name='source' value='/Ribbon/XAPS/RibbonGalleryControl.xap'/&gt;&lt;param name='initParams' value='MS.SP.url=http://johnnyt-i7/ribbon'/&gt;&lt;param name='background' value='white' /&gt;&lt;param name='minRuntimeVersion' value='4.0.50303.0' /&gt;&lt;param name='autoUpgrade' value='true' /&gt;&lt;a href='http://go.microsoft.com/fwlink/?LinkID=149156&amp;v=4.0.50303.0' style='text-decoration:none'&gt;&lt;img src='http://go.microsoft.com/fwlink/?LinkId=161376' alt='Get Microsoft Silverlight' style='border-style:none'/&gt;&lt;/a&gt;&lt;/object&gt;&lt;iframe id='_sl_historyFrame' style='visibility:hidden;height:0px;width:0px;border:0px'&gt;&lt;/iframe&gt;&lt;/div&gt;" ElementDimensions="Size190by60" />

 Attributes In Focus:

  • TemplateAlias - This attribute defines where the control will render in our template. We will see how it's used later when we define the group template.
  • InnerHTML - The golden boy of this element. This attribute let us type HTML that the control will render.
    Few important things to remember about this attribute:
    1) It only accepts HTML Encoded text (i.e.: &gt; instead of > or &amp; instead of &), so when you work with Silverlight you have to encode your object tag to HTML first.
    2) The source parameter must point to the location of the .xap file. You can use either relative or absolute url.
    3) MS.SP.url parameter must be defined at the initParams section and point to the absolute url of your site. The value of this parameter is used by the client object model to identify its context.
  • ElementDimension - This attribute sets the size of the control. The values are selected from an enum of available sizes.

10) At this point your xml should look similar to this:

<?xml version="1.0" encoding="utf-8"?>
    <
Elements xmlns="http://schemas.microsoft.com/sharepoint/">
        <
CustomAction Id="Ribbon.SilverlightExample" RegistrationType="List" RegistrationId="101" Location="CommandUI.Ribbon">
            <
CommandUIExtension>
                <
CommandUIDefinitions>
                    <
CommandUIDefinition Location="Ribbon.Tabs._children">
                        <
Tab Id="Ribbon.SilverlightExample" Sequence="501" Description="My New Silverlight control Tab" Title="My Silverlight Tab">
                            <
Scaling Id="Ribbon.SilverlightExample.scaling">
                                <
MaxSize Id="Ribbon.SilverlightExample.scaling.MaxSize" GroupId="Ribbon.SilverlightExample.GalleryGroup" Size="OneLarge"/>
                                <
Scale Id="Ribbon.SilverlightExample.scaling.customScaling" GroupId="Ribbon.SilverlightExample.GalleryGroup" Size="OneLarge"/>
                             </
Scaling>
                             <
Groups Id="Ribbon.SilverlightExample.Groups">
                                 <
Group Id="Ribbon.SilverlightExample.GalleryGroup" Description="This is the Silverlight control group" Title="Silverlight Control Group" Sequence="52" Template="Ribbon.Templates.SilverlightExampleTemplate">
                                     <
Controls Id="Ribbon.SilverlightExample.Controls">
                                         <
GalleryButton TemplateAlias="control1" Id="SilverlightControl" InnerHTML="..." ElementDimensions="Size190by60" />
                                     </
Controls>
                                 </
Group>
                             </
Groups>
                         </
Tab>
                     </
CommandUIDefinition>
                 </
CommandUIDefinitions>
             </
CommandUIExtension>
        </
CustomAction>
    </
Elements>

We are done with the tab definition and we are now moving on to the template definition.
Add the following code right after the closing CommandUIDefinition elements:

<CommandUIDefinition Location="Ribbon.Templates._children">
    <
GroupTemplate Id="Ribbon.Templates.SilverlightExampleTemplate">
       
<Layout Title="OneLarge" LayoutTitle="OneLarge">
       
</Layout>
    </
GroupTemplate>
</
CommandUIDefinition>

 Attributes In Focus:

  • Location - For this CommandUIDefinition our location has changed to Ribbon.Templates._children because we are now defining a template and templates have a different collection then tabs.
  • Id - Unlike the previous times i mentioned the Id attribute, this time you can't just give it any name you like. If you look up you will see that for the Group element we defined an attribute called Template - the GroupTemplate id must match it in order for the template to be associated with a group.
  • Title - Must match the Size attribute of the Scale and MaxSize elements we defined earlier. This is how the scale gets associated with a layout.

11) The last thing we need to define for our template is section. Think of a section as the layout of a group - the way the controls are ordered inside of it.
Add the following code between the opening and closing Layout elements:

<Section Alignment="Top" Type="OneRow">
    <
Row>
        <
ControlRef TemplateAlias="control1" DisplayMode="Large"/>
    </
Row>
</
Section>

 Attributes In Focus:

  • Alignment - This attribute defines how to align controls inside of a row. Can be set to either Top or Middle.
  • Type - This attribute defines how many rows the section will have. The maximum is three rows.
  • TemplateAlias - This attribute tells the ControlRef element what item it positions by referencing a control with the same TemplateAlias. The controlRef element defines how a single control renders in the ribbon.
  • DisplayMode - This attribute defines the style for the control's icon and label text. Please refer here for a complete list of possible values.

12) The last element we need to add to our xml is the CommandUIHandlers. This element contains a collection of commands for our ribbon. We won’t deal with commands in this post (it's long enough as it is) so just add the following code after the closing CommandUIDefinitions element:

<CommandUIHandlers>
    <
CommandUIHandler Command="" CommandAction=""/>
</
CommandUIHandlers>

13) Click on the SharePoint project name in the solution explorer window (SharePointRibbonSLPOC) and set the Site URL property to your site collection url.

14) Right click on SharePointSLPOC and choose "Deploy".

15) Open your browser and navigate to your site collection. Create a new Picture Library and name it as you like.
Upload some images to the picture library you have just created.

16) Navigate to any document library on your site (for example Shared Documents) and watch our newly created tab in action ;)

Let's summarize what we have done so far:

1) We created a Silverlight control to show images from a random picture library.
2) We defined a CustomAction that deploys a custom tab control that is added to any document library on our site.
3) We added a GalleryButton to our custom tab control and set its InnerHTML attribute to render our Silverlight control.
4) We deployed the solution to our SharePoint site.

I hope you enjoyed the series so far. If you want a copy of this solution you can download it right here.

In part 3 of the series we will take our custom tab control and change its scope from list level to site level, so stay tuned ;)

You can see a nice use for a custom SharePoint tab at my CodePlex project: SharePoint Social Networking.

I hope this helps to ease the pains of customizing the SharePoint ribbon control.
Please feel free to contact me if you run into any issues or questions.

Published Thursday, February 03, 2011 11:14 PM by johnnyt

Comments

# SharePoint Silverlight | Web-Resource.org Blog

Saturday, March 26, 2011 5:18 PM by SharePoint Silverlight | Web-Resource.org Blog

Pingback from  SharePoint Silverlight | Web-Resource.org Blog

# Fun with Silverlight and SharePoint 2010 Ribbon Control | allaboutmoss

Pingback from  Fun with Silverlight and SharePoint 2010 Ribbon Control | allaboutmoss

Leave a Comment

(required) 
(required) 
(optional)
(required) 

Enter the numbers above:
Powered by Community Server (Commercial Edition), by Telligent Systems