Andrei Smolin

Make the Office 2007 Ribbon work easy

Microsoft Office 2007 allows XML-based customizations for its Ribbon UI (user-interface). To achieve this, you, the developer, need to generate a string that contains a markup specifying custom ribbon controls and their properties as well as names of event handler procedures for these controls. Then, in an appropriate moment, you should supply the host application with the string. If the string is correct, the controls will be shown and you will get their events in the procedures which names you specified.

Say, if the event handler for your Office 2007 Ribbon button is called MyEventHandler, the XML must contain this name in the following way:

<customui xmlns="">
      <tab idMso="MyTab">
        <group id="MyGroup" label="My Group">
          <button id="button1"
                    label="My Button"
                    screentip="My Button Screentip"
                    imageMso="HappyFace" />

The only way to make sure that the XML above is correct is to run your add-in. That is, you can’t check if your XML is valid at design-time. All my life I have been told that run-time warnings cost more than compile-time ones. Haven’t you?

There is another source of troubles: the signature of the method should conform to the rules described in manuals (see Downloads in the end of this post). However, if the signature of your method doesn’t correspond to that required by the Office 2007 Ribbon (say, if you add an extra parameter, mistakenly, of course), you’ll be never informed about this and your event handler will never be called. Nice, isn’t it?

These error-prone and time-consuming issues are successfully resolved in Add-in Express 2007 by introducing the Office 2007 Ribbon tab designer.

With this Ribbon tab designer, you never have to deal with XML. Instead, you create the UI right in the designer that generates appropriate Ribbon components, events of which are handled in the usual manner.

For instance, let’s create a custom group with a custom Ribbon button on a custom tab in Excel 2007:

A ribbon button in the Office 2007 Ribbon tab designer

Now we handle the Click event of the button:

Handling the Click event of a ribbon button

After that re-target the group to the TabHome built-in tab:

The tab now targets to the TabHome built-in tab.

That’s easy. However, the potential of our approach to the Office 2007 Ribbon UI customization becomes even more evident now, when Visual Studio 2008 includes the Ribbon designer for its VSTO 3 projects. Note that VSTO 3 is integrated with VS 2008; it provides project templates in the Office Visual Basic / Office and Visual C# / Office nodes of the New Project dialog in Visual Studio 2008.

To start with, Add-in Express 2008 for Office and .NET supports all Microsoft Office versions and, accordingly, you needn’t have several code bases for different Office versions. Instead, you create just one project that works for all Office versions. That is, you can just use the Ribbon visual designer in your project and the corresponding Ribbon XML markup will be generated, verified and transferred to Office 2007 with no extra steps from you part. I’m sure, the last feature is exactly what any developer would expect from the designer. But this isn’t the case with the Visual Studio 2008 designer. It is available for projects targeting Office 2007 only. I don’t like to speculate on why Microsoft chooses this or that way. Nevertheless, the fact is that if you need to support both Office 2003 and 2007, you need to create two VSTO projects: one for Office 2003 and another one for Office 2007.

Now I want to compare both Ribbon designers: Add-in Express’ and VSTO’s. Let me be honest and start from flaws in the Add-in Express Ribbon tab designer. Currently, I see two of them: first, our Office 2007 Ribbon tab designer allows designing a single tab only and second, it has a design-time defect in drawing items of a list, combo, and gallery. On the other hand, Microsoft’s designer supports designing many tabs and hopefully they display every tiny thing in their designer correctly.

Both designers provide quite similar features: you can design and handle any custom Ribbon controls: button groups, buttons, list boxes, combo boxes etc. You can target any control to a built-in or custom tab. Both Add-in Express and VSTO 3 generate XML from their designers transparently.

The most evident distinction between designers lies on the surface, however. In VSTO, the designer is just a designer. While in Add-in Express, the designer is part of the component set purposed for constructing the UI of your Office 2007 add-in. Let’s take built-in Ribbon controls. Neither of the designers allows you to process a built-in ribbon control. But Add-in Express provides a special component, RibbonCommand that allows connecting to any built-in ribbon control and handling its events without the need to dig into XML.

For instance, see how to disable the Copy command in Word 2007.

Built-in Ribbon command

As to VSTO 3, it includes the Ribbon (XML) item available in the Add New Item dialog (for projects targeting Office 2007 only). This approach adds some more flies to the ointment; just read comments in the file created when the Ribbon (XML) item is run:

  • Copy a code block to this or that class
  • Create callbacks and note some special case
  • Add callback names to appropriate attributes of appropriate control tags in the XML file.

R-r-r-r! :)

Here, at Add-in Express we are working on simplifying and speeding up the development of Office COM add-ins. That’s why Add-in Express Ribbon UI designer gives you the possibility to share Ribbon controls across multiple add-ins. Note that this requires manual operations in VSTO 3.

Here is the source code that creates the above mentioned Ribbon components (Ribbon tab that contains a ribbon group containing a ribbon button). Note that the tab is shown only when the user composes or edits an e-mail in Outlook 2007.

[VB.NET code]

Private Sub InitializeComponent()
   Me.components = New System.ComponentModel.Container
   Dim resources As System.ComponentModel.ComponentResourceManager = 
New System.ComponentModel.ComponentResourceManager(GetType(AddinModule))
   Me.RibbonTab = New AddinExpress.MSO.ADXRibbonTab(Me.components)
   Me.RibbonGroup = New AddinExpress.MSO.ADXRibbonGroup(Me.components)
   Me.RibbonButton = New AddinExpress.MSO.ADXRibbonButton(Me.components)
   Me.ImageList1 = New System.Windows.Forms.ImageList(Me.components)
   Me.RibbonTab.Caption = "My Ribbon Tab"
   Me.RibbonTab.Id = "adxRibbonTab_33d6c3f63d17474db7bc3a04e1b1e7d9"
   Me.RibbonTab.Ribbons = AddinExpress.MSO.ADXRibbons.msrOutlookMailCompose
   Me.RibbonGroup.Caption = "My Ribbon Group"
   Me.RibbonGroup.Id = "adxRibbonGroup_65d7dab572ef41f7b462701d5210256c"
   Me.RibbonGroup.Ribbons = AddinExpress.MSO.ADXRibbons.msrOutlookMailCompose
   Me.RibbonButton.Caption = "My Ribbon Button"
   Me.RibbonButton.Id = "adxRibbonButton_8257f64d29104b11a37ceb4b65f69359"
   Me.RibbonButton.Image = 0
   Me.RibbonButton.ImageTransparentColor = System.Drawing.Color.Transparent
   Me.RibbonButton.Ribbons = AddinExpress.MSO.ADXRibbons.msrOutlookMailCompose
   Me.RibbonButton.Size = AddinExpress.MSO.ADXRibbonXControlSize.Large
   Me.ImageList1.ImageStream = CType(resources.GetObject("ImageList1.ImageStream"), 
   Me.ImageList1.TransparentColor = System.Drawing.Color.Transparent
   Me.ImageList1.Images.SetKeyName(0, "account_actions_24.png")
   Me.AddinName = "MyAddin7"
   Me.Images = Me.ImageList1
   Me.SupportedApps = AddinExpress.MSO.ADXOfficeHostApp.ohaOutlook

End Sub

[C# code]

private void InitializeComponent()
   this.components = new System.ComponentModel.Container();
   System.ComponentModel.ComponentResourceManager resources =
 new System.ComponentModel.ComponentResourceManager(typeof(AddinModule));
   this.RibbonTab = new AddinExpress.MSO.ADXRibbonTab(this.components);
   this.RibbonGroup = new AddinExpress.MSO.ADXRibbonGroup(this.components);
   this.RibbonButton = new AddinExpress.MSO.ADXRibbonButton(this.components);
   this.imageList1 = new System.Windows.Forms.ImageList(this.components);
   // RibbonTab
   this.RibbonTab.Caption = "My Ribbon Tab";
   this.RibbonTab.Id = "adxRibbonTab_04dee6e0f08a4f8fa31f0f5982a998c7";
   this.RibbonTab.Ribbons = AddinExpress.MSO.ADXRibbons.msrOutlookMailCompose;
   // RibbonGroup
   this.RibbonGroup.Caption = "My Ribbon Group";
   this.RibbonGroup.Id = "adxRibbonGroup_74cbaba4b40444e6b45f1b8d9570410d";
   this.RibbonGroup.Ribbons = AddinExpress.MSO.ADXRibbons.msrOutlookMailCompose;
   // RibbonButton
   this.RibbonButton.Caption = "My Ribbon Button";
   this.RibbonButton.Id = "adxRibbonButton_6f220d15d7824b048e09e627e77f4227";
   this.RibbonButton.Image = 0;
   this.RibbonButton.ImageTransparentColor = System.Drawing.Color.Transparent;
   this.RibbonButton.Ribbons = AddinExpress.MSO.ADXRibbons.msrOutlookMailCompose;
   this.RibbonButton.Size = AddinExpress.MSO.ADXRibbonXControlSize.Large;
   // imageList1
   this.imageList1.ImageStream = ((System.Windows.Forms.ImageListStreamer)
   this.imageList1.TransparentColor = System.Drawing.Color.Transparent;
   this.imageList1.Images.SetKeyName(0, "account_actions_24.png");
   // AddinModule
   this.AddinName = "MyAddin8";
   this.Images = this.imageList1;
   this.SupportedApps = AddinExpress.MSO.ADXOfficeHostApp.ohaOutlook;


Andrei Smolin
Add-in Express Team Leader

Related posts:

Customize Office toolbars, ribbons, task panes on RO Chrome
Create Office add-ins: ribbons, toolbars, task panes, menus

Post a comment

Have any questions? Ask us right now!