Saturday, January 9, 2010

SharePoint 2010 Ribbon Customization Part III: How to add custom Contextual tabs into Ribbon?

In This Article I will cover how we can have custom contextual group tabs at various locations.

In above image you can see,
  • A new custom contextual Tab “aQura” with tab “2W Series”
  • A custom tab “2W Series” has been added to default List’s contextual Tab “List Tools”
  • A single tab “aQura” with contextual tab has been added to list view
So we can move custom tab at various locations on form. Let’s see how?

Custom Contextual Tab:

Behind the scene, CUI.RibbonBuilder and CUI.RibbonBuildOptions classes are responsible for initializing Ribbon on client side. After you deploy above configuration you won’t find any custom Contextual tab for your list. The reason is CUI.RibbonBuildOptions doesn’t populate its shownTabs & initiallyVisibleContextualGroups properties with proper values. They populated with default values. You can check these properties through page’s view source. How we can instruct ribbon that, this is a new Contextual Tab and you should show whenever page gets rendered? To do so we need to access Ribbon control from the context. Once we get the Object of current ribbon then we will set the New Contextual Tab and Its all child tabs.
To do so we have two options,
  • Override a delegate control on the page.
  • Put a Web Part on the page.
Replacing a delegate should be used when working with a document library or list. The AdditionalPageHead delegate can be used to host our custom user control. Within that user control, we will access the current ribbon object. Web Parts can be placed on the page and on load of that web part we can easily access the ribbon object. Up to a great extension this is very handy solution but in case of ListView form we do not have freedom to put webpart on that page. So I prefer Delegate Control.
By adding control element into xml declaration of custom action we can instruct the OOB “AdditionalPageHead” delegate control to host our custom user control.

SPRibbon’s GetCurrent method returns the Ribbon object belonging to the page in context. Then by accessing MakTabAvailable method we are instructing ribbon to insert mention tab while rendering. Then by accessing MakeContextualGroupInitiallyVisible method we are instructing ribbon to make our custom Contextual group visible.

Adding Custom Tab to OOB ContextualTab:

Adding Custom Tab to ListView without any contextual tab:

That’s all, deploy the solution and see the results. You will see the tab has been added to list view form without any contextual tab. What I have changed is Location attribute of Custom Action. “CommandUI.Ribbon” instructs that create a tab but its scope will be global. Also I have removed RegistrationID and RegistrationType attributes. By doing this now I have a global tab which neither bind to any list nor have any predefined location.

Next I need to instruct that while rendering my list, Ribbon should have this tab. How I can achieve this? By overriding Delegate Control, I have explained how to override Delegate Control in one of the above topic. Below is the code we need into user control.

Note: While working on ribbon customization, keep deleting IE’s temporary files. Otherwise results will be unexpected.





    Help me PLEASE!!!! Thank you! NICE BLOG!!!

  3. You are the man!
    Can you please post the source code please?

  4. I added Ribbon with few buttons. The Problem comes after adding the page viewer webpart to the page i.e..All the ribbon buttons got disabled.

    Can you suggest me the reason

  5. Any idea why the OOTB "List Tools" tabs are duplicated? but duplicates disappear once user uses the ribbon

  6. To be honest, your source code doesn't really make sense.

    You have a javscript file going to your LAYOUTS directory that isn't referenced anywhere else in your solution. And then you have a script manager helper class that isn't referenced anywhere either.

    I should be able to understand this solution, but it's not organized in a logical manner.

    Your example on this page also is incorrect as line 3 of your last C# code example should reference the tab ID of "Ribbon.aQura.SingleTab" based on the Elements.xml file immediately above.

  7. This comment has been removed by the author.