Sharing a Ribbon Customization Between Office Projects in Visual Studio 2010 (McLean Schofield)

  • Comments 2

A customer on the VSTO forums recently noticed that the steps we blogged about for sharing a single Ribbon customization between multiple projects in Visual Studio 2008 no longer works in Visual Studio 2010. When following the instructions in the blog post, you get an error when you try to open the Ribbon code file in the class library project. This is because of some changes to the way the Ribbon designer was implemented in Visual Studio 2010. The upshot is that you can no longer open the Ribbon designer outside of Office projects. In addition, because Office projects that target the .NET Framework 4 have a different programming model in Visual Studio 2010, the instructions in the old blog post will also result in other errors in projects that target the .NET Framework 4.

This blog post tells you how to share a single Ribbon customization (created by using the Ribbon designer) between multiple Office projects in Visual Studio 2010. Disclaimer – what I am about to show you in this blog post is not supported, and has not been officially tested by the product team in any way.

Targeting the .NET Framework 3.5

If your Office projects target the .NET Framework 3.5, then the instructions in the old blog post still apply, with just one change. Rather than design your Ribbon customization in the class library project, now you must design it in an Office project, because of the change to the implementation of the Ribbon designer noted above. Here are the modified instructions.

  1. In Visual Studio, open (or create) an Office project that targets the .NET Framework 3.5, and that targets an Office application that supports the Ribbon.
  2. Add a Ribbon (Visual Designer) item to the project.
  3. Design your Ribbon customization. Be sure to set the Modifiers property to Public for any controls/tabs/groups that you want to be able to access in other Office projects. Also be sure to set the RibbonType property of the Ribbon to all Ribbon types you want to support in other Office projects that consume the shared Ribbon. For example, if you want to use the Ribbon customization in Excel and Word projects, set RibbonType to Microsoft.Excel.Workbook and Microsoft.Word.Document.
  4. Save your changes.
  5. Create a class library project that targets the .NET Framework 3.5. Add the following reference:
    • Microsoft.Office.Tools.Common.v9.0
  6. Add the existing Ribbon code file to the class library project. The code-behind file (for example, Ribbon1.Designer.cs) will be copied over automatically.
  7. Optionally, open the Ribbon file and the code-behind file in the editor and change the namespaces for the Ribbon class in the main Ribbon file and code-behind file (for example, to SharedRibbonLibrary or some other namespace that identifies your component). Be sure to open the files in the editor by right-clicking them and choosing View Code. Do not double-click the files; this will attempt to open the Ribbon designer, and will result in a designer error.
  8. Build the class library project.
  9. In a new/different Office project that targets the .NET Framework 3.5, add a reference to the class library project.
  10. In the ThisAddIn, ThisDocument, or ThisWorkbook class in the Office project, override CreateRibbonObjects as follows (the following code assumes you changed the namespace of the shared Ribbon to SharedRibbonLibrary).
    protected override Microsoft.Office.Core.IRibbonExtensibility CreateRibbonExtensibilityObject()
    {
    return new Microsoft.Office.Tools.Ribbon.RibbonManager(
    new Microsoft.Office.Tools.Ribbon.OfficeRibbon[] {
    new SharedRibbonLibrary.Ribbon1() });
    }

  11. Add the following class to the project. This code lets you access the shared Ribbon customization by using Globals.Ribbons in your code.
    partial class ThisRibbonCollection : Microsoft.Office.Tools.Ribbon.RibbonReadOnlyCollection
    {
    internal SharedRibbonLibrary.Ribbon1 Ribbon1
    {
    get { return this.GetRibbon<SharedRibbonLibrary.Ribbon1>(); }
    }
    }

  12. Now you can use Globals.Ribbons.Ribbon1 to access public items exposed by the shared Ribbon. For example:
    private void ThisAddIn_Startup(object sender, System.EventArgs e)
    {
    Globals.Ribbons.Ribbon1.button1.Click += new EventHandler<Microsoft.Office.Tools.Ribbon.RibbonControlEventArgs>(button1_Click);
    }

    void button1_Click(object sender, Microsoft.Office.Tools.Ribbon.RibbonControlEventArgs e)
    {
    System.Windows.Forms.MessageBox.Show("it works!");
    }


Targeting the .NET Framework 4

If your Office projects target the .NET Framework 4, you’ll need to make a number of other changes to the Ribbon code. Here are the full instructions.

  1. In Visual Studio, open (or create) an Office project that targets the .NET Framework 4, and that targets an Office application that supports the Ribbon.
  2. Add a Ribbon (Visual Designer) item to the project.
  3. Design your Ribbon customization. Be sure to set the Modifiers property to Public for any controls/tabs/groups that you want to be able to access in other Office projects. Also be sure to set the RibbonType property of the Ribbon to all Ribbon types you want to support in other Office projects that consume the shared Ribbon. For example, if you want to use the Ribbon customization in Excel and Word projects, set RibbonType to Microsoft.Excel.Workbook and Microsoft.Word.Document.
  4. Save your changes.
  5. Create a class library project that targets the .NET Framework 4. Add the following references:
    • Microsoft.Office.Tools
    • Microsoft.Office.Tools.Common
    • Microsoft.Office.Tools.Common.v4.0.Utilities
  6. Add the existing Ribbon code file to the class library project. The code-behind file (for example, Ribbon1.Designer.cs) will be copied over automatically.
  7. Open the Ribbon file and code-behind file in the code editor by right-clicking them and choosing View Code. Do not double-click the files; this will attempt to open the Ribbon designer, and will result in a designer error.
  8. In the Ribbon code-behind file, change the constructor to the following.
    public Ribbon1(Microsoft.Office.Tools.Ribbon.RibbonFactory factory)

    : base(factory)

    {

    InitializeComponent();

    }

  9. In Ribbon code-behind file, remove the ThisRibbonCollection class definition at the bottom of the file. 
  10. Optionally, change the namespaces for the Ribbon class in the main Ribbon file and code-behind file (for example, to SharedRibbonLibrary or some other namespace that identifies your component).
  11. Build the class library project.
  12. In a new/different Office project that targets the .NET Framework 4, add a reference to the class library project.
  13. In the ThisAddIn, ThisDocument, or ThisWorkbook class in the Office project, override CreateRibbonObjects as follows (the following code assumes you changed the namespace of the shared Ribbon to SharedRibbonLibrary).
    protected override Microsoft.Office.Tools.Ribbon.IRibbonExtension[] CreateRibbonObjects()

    {

    return new Microsoft.Office.Tools.Ribbon.IRibbonExtension[] { new

    SharedRibbonLibrary.Ribbon1(Globals.Factory.GetRibbonFactory()) };

    }

  14. Add the following class to the project. This code lets you access the shared Ribbon customization by using Globals.Ribbons in your code.
    partial class ThisRibbonCollection : Microsoft.Office.Tools.Ribbon.RibbonReadOnlyCollection

    {

    internal SharedRibbonLibrary.Ribbon1 Ribbon1

    {

    get { return this.GetRibbon<SharedRibbonLibrary.Ribbon1>(); }

    }

    }


  15. Now you can use Globals.Ribbons.Ribbon1 to access public items exposed by the shared Ribbon. For example:
    private void ThisAddIn_Startup(object sender, System.EventArgs e)
    {
    Globals.Ribbons.Ribbon1.button1.Click += new Microsoft.Office.Tools.Ribbon.RibbonControlEventHandler(button1_Click);
    }

    void button1_Click(object sender, Microsoft.Office.Tools.Ribbon.RibbonControlEventArgs e)
    {
    System.Windows.Forms.MessageBox.Show("it works!");
    }

Leave a Comment
  • Please add 1 and 8 and type the answer here:
  • Post
  • I have this working quite well in .NET4 in Excel/PPT/Word. I coupled your code with the Outlook Inspector wrapper (msdn.microsoft.com/.../ff973716.aspx), and get errors on the second email inspector instance (first can be open or closed). The first email instance seems to be ok. The error is long...something like:

    An exception occurred while calling function "GetVisible". The exceptino message is:

    Thrown exception of typ System.MissingMethodException with message" "No parameterless constructor defined for this object."

    Stack trace.....

    {stuff}

    at Microsoft.Office.Tools.Ribbon.RibbonManagerImpl.System.Reflection.IReflect.InvokeMember( ---stuff --)

  • Same here, it works on Excel and Word, but it won't work on Outlook if the ribbon is on each email inspector.

Page 1 of 1 (2 items)

Sharing a Ribbon Customization Between Office Projects in Visual Studio 2010 (McLean Schofield)