Follow the example illustrated in http://blog.dennus.net/2010/07/20/ribbon-buttons-with-postback-in-sp2010/, rather than using declarative approach in this example, I created custom web part class and registered ribbon data extension, pageComponent script and etc. during OnPreRender event.
Everything appears to be working just fine, I got my contextual group/tab/control rendered when web part page is displayed. However, if I add two of my custom web parts on the same page, I ran into error: ArgumentException: Item has already been added. Key in dictionary: 'Ribbon.MyContextualTabGroup' Key being added: 'Ribbon.MyContextualTabGroup'].
How can I avoid this problem? What is the best approach? Ideally I would like the ribbon contextual group/tab/control render differently when different custom web part on the page is selected but I missed how that part works in SharePoint 2010 Ribbon framework.
In an attempt to detect that the first web part on the page may have registered the contextual group, I tried SPRibbon.IsTabAvailable(tabID) but this always returns me true - even before I actually added the tab XML data extension. I am quite confused. Note I did not use the Custom Action/feature deployment approach but dynamically register ribbon data extension and page component.
Below are code snippet showing how I added the ribbon:
Microsoft.Web.CommandUI.Ribbon ribbon = SPRibbon.GetCurrent(theWebPart.Page);
if (ribbon != null)
{
// register data extension
XmlDocument ribbonExtensions = new XmlDocument();
ribbonExtensions.LoadXml(ContextualGroupInfo.ToXml());
ribbon.RegisterDataExtension(ribbonExtensions.FirstChild,
"Ribbon.ContextualTabs._children");
// Register initialize function
var manager = new SPRibbonScriptManager();
var methodInfo = typeof(SPRibbonScriptManager).GetMethod(
"RegisterInitializeFunction",
System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
methodInfo.Invoke(manager, new object[]
{
webPart.Page,
"InitPageComponent",
"/_layouts/PageComponent.js",
false,
"RibbonCustomization.PageComponent.initialize()"
});
var commands = new List();
commands.Add(new SPRibbonCommand(ContextualGroup.EnableContextualGroupCommand));
commands.Add(new SPRibbonCommand(ContextualTab.EnableContextualTabCommand));
...
// add ribbon button commands
...
// initialize tab
ribbon.Minimized = false;
ribbon.CommandUIVisible = true;
if (!ribbon.IsTabAvailable(ContextualTab.ID))
{
ribbon.MakeTabAvailable(ContextualTab.ID);
ribbon.EnableVisibilityContext(ContextualTab.VisibilityContext);
ribbon.MakeContextualGroupInitiallyVisible(ContextualTabGroupID, string.Empty);
ribbon.NormalizeContextualGroup(ContextualTabGroupID, string.Empty);
}
// Make the tab active by default when the page is opened.
ribbon.InitialTabId = ContextualTab.ID;
...
}