Hi,
I have the following code for a custom contextual tab, with a post back event handler, which is similar to many posted examples.
This code has no issues on SP 2010, but after converting to 2013, clicking the post back button causes a duplicate tab to display.
e.g. : My Test Tab My Test Tab, if the left instance of the tab name is clicked then the second disappears.
Any help is appreciated.
using System;
using System.ComponentModel;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using System.Xml;
using Microsoft.Web.CommandUI;
using System.Collections.Generic;
namespace RDWB.RDWBWebpart
{
[ToolboxItemAttribute(false)]
public class RDWBWebpart : WebPart, IWebPartPageComponentProvider, IPostBackEventHandler
{
private string demoContextualTab = @"
<ContextualGroup Color=""Magenta""
Command=""CustomContextualTab.EnableContextualGroup""
Id=""Ribbon.CustomContextualTabGroup""
Title=""Custom Contextual Tab Group""
Sequence=""502""
ContextualGroupId=""CustomContextualTabGroup"">
<Tab
Id=""Ribbon.CustomTabExample""
Title=""My Test Tab""
Description=""My Test Tab""
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""
Image32by32=""/_layouts/15/images/radio_blue_32.png""
Description=""Says hello to the World!""
LabelText=""Hello, World!""
TemplateAlias=""cust1""/>
<Button
Id=""Ribbon.CustomTabExample.CustomGroupExample.GoodbyeWorld""
Command=""CustomContextualTab.GoodbyeWorldCommand""
Sequence=""17""
Image16by16=""/_layouts/15/images/HelloWorld.png""
Description=""Says good-bye to the World!""
LabelText=""Good-bye, World!""
TemplateAlias=""cust2""/>
</Controls>
</Group>
</Groups>
</Tab>
</ContextualGroup>";
private string demoContextualTabTemplate = @"
<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>";
public string DelayScript
{
get
{
//This gets a unique reference for the instance of your Web Part, on the current page, in the context of the Ribbon.
//This is used to effectively identify your Web Part when someone clicks on it!
string webPartPageComponentId = SPRibbon.GetWebPartPageComponentId(this);
return @"
<script type=""text/javascript"">
//<![CDATA[
function _addCustomPageComponent()
{
var _customPageComponent = new PostbackContextualDemo.PostbackPageComponent('" + webPartPageComponentId+ @"');
SP.Ribbon.PageManager.get_instance().addPageComponent(_customPageComponent);
}
function _registerCustomPageComponent()
{
SP.SOD.registerSod(""PostbackContextualDemo.js"", ""\/_layouts\/PostbackContextualDemo.js"");
SP.SOD.executeFunc(""PostbackContextualDemo.js"", ""PostbackContextualDemo.PostbackPageComponent"",
_addCustomPageComponent);
}
SP.SOD.executeOrDelayUntilScriptLoaded(_registerCustomPageComponent, ""sp.ribbon.js"");
//]]>
</script>";
//SP.SOD.executeOrDelayUntilScriptLoaded above: This is the new “Script On Demand” (SOD) method which allows us to
tell SharePoint not to try loading our JavaScript until the SP.Ribbon.JS has already been processed!
}
}
private void AddContextualTab()
{
//Gets the current instance of the ribbon on the page.
Microsoft.Web.CommandUI.Ribbon ribbon = SPRibbon.GetCurrent(this.Page);
//Prepares an XmlDocument object used to load the ribbon extensions.
XmlDocument ribbonExtensions = new XmlDocument();
//Load the contextual tab XML
ribbonExtensions.LoadXml(this.demoContextualTab);
//Register the ribbon extension.
ribbon.RegisterDataExtension(ribbonExtensions.FirstChild, "Ribbon.ContextualTabs._children");
//Load the custom templates
ribbonExtensions.LoadXml(this.demoContextualTabTemplate);
// Register the ribbon extension
ribbon.RegisterDataExtension(ribbonExtensions.FirstChild, "Ribbon.Templates._children");
// needed ?, not in examples ...
ribbon.MakeTabAvailable("Ribbon.CustomTabExample");
//ribbon.MakeContextualGroupInitiallyVisible("Ribbon.CustomTabExample.CustomGroupExample", "CustomContextualTab.CustomVisibilityContext");
}
WebPartContextualInfo IWebPartPageComponentProvider.WebPartContextualInfo
{
get
{
// create objects for the contextual web part tab
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);
return info;
}
}
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
this.AddContextualTab();
string script = @"
function _registerPostBackPageComponent()
{
var postBackPageComponent = new PostbackContextualDemo.PostbackPageComponent();
SP.Ribbon.PageManager.get_instance().addPageComponent(postBackPageComponent);
}
ExecuteOrDelayUntilScriptLoaded(_registerPostBackPageComponent, ""PostbackContextualDemo.js"");
";
ScriptLink.RegisterScriptAfterUI(Page, "CUI.js", false, true);
ScriptLink.RegisterScriptAfterUI(Page, "SP.Ribbon.js", false, true);
ScriptLink.RegisterScriptAfterUI(Page, "PostbackContextualDemo.js", false, true);
Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "postbackpagecomponent", script, true);
SPRibbonScriptManager ribbonScript = new SPRibbonScriptManager();
List<IRibbonCommand> globalCommands = new List<IRibbonCommand>();
globalCommands.Add(new SPRibbonCommand("CustomContextualTab.EnableCustomTab"));
globalCommands.Add(new SPRibbonCommand("CustomContextualTab.EnableCustomGroup"));
globalCommands.Add(new SPRibbonCommand("CustomContextualTab.GoodbyeWorldCommand"));
globalCommands.Add(new SPRibbonPostBackCommand("CustomContextualTab.HelloWorldCommand", this));
ribbonScript.RegisterHandleCommandFunction(this, "handleCommand", globalCommands);
}
protected override void Render(HtmlTextWriter writer)
{
base.Render(writer);
writer.Write("Ribbon Post back Demo");
}
protected override void RenderContents(HtmlTextWriter writer)
{
base.RenderContents(writer);
}
void IPostBackEventHandler.RaisePostBackEvent(string eventArgument)
{
SPRibbonPostBackEvent postBackEvent = SPRibbonPostBackCommand.DeserializePostBackEvent(eventArgument);
if (null != postBackEvent)
{
if (postBackEvent.Id == "CustomContextualTab.HelloWorldCommand")
{
HelloWorldCommand_Click();
}
}
}
protected void HelloWorldCommand_Click()
{
}
}
}