A code monkey in Research

One developer's view of (a little bit of) Microsoft Research, Cambridge

Adding some ribbon XML

The first thing to do to the project started earlier is to add something to the Outlook ribbon. Right click on the project and select “add new item.” You’ll see two ribbon related options, the first being “Ribbon (Visual Designer)” – this offers an easy to use visual editor for ribbon controls and a means of setting up event handlers that should be familiar to people who have programmed with windows Forms or WPF. However, I don’t think it’s as flexible as the other option, “Ribbon (XML),” which is what I’m going to use here. If you want to find out more about the visual designer, check out the MSDN documentation.

So, go ahead and add a ribbon – call it ComposeRibbon (for reasons which will become clear in a later post). Note the TODO comments at the head of the ComposeRibbon.cs file, in particular the one about copying the ribbon creation call into ThisAddIn.cs. Having done that, hit F5 and you’ll see a new tab with a “My Group” label in it on the Outlook ribbon. Now, although Visual Studio added both an XML file and a C# source file with the same name, a project can have several distinct ribbon XML definitions but at most only a single ribbon C# file – when I wanted to have separate ribbons for the mail composition window and the mail reading window I did quite a bit of head scratching before I eventually realised this. Rename ComposeRibbon.cs to Ribbon.cs to help keep the two notions separate in your mind.

Replace the contents of ComposeRibbon.xml with the following:

<?xml version="1.0" encoding="UTF-8"?>
<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui" onLoad="Ribbon_Load">
      <tab idMso="TabNewMailMessage">
        <group id="grpReply" label="Response Options">
          <toggleButton id="btnNoReplyAll"
                        screentip="No Reply All"
                        supertip="Prevent recipients within the same organisation from replying to all"
                        label="No Reply All"
                        size="large" />

A couple of things I want to draw your attention to are the MSO named properties in the tab and toggleButton elements, shown in bold above – these refer to items that exist in the Office (Outlook in this case) ribbon and resource definitions, respectively the main tab that appears (only) in the mail composition window and a graphic normally used for distribution list management, but which sort of fits here since it’s a picture of a person with a minus sign overlay. You can find a list of these id values in this download, though it’s more of a tantalising hint about what’s available than a complete description. In the first case, the property identifies where in the UI our new matter should appear; in the second case, I’m lazily using a predefined graphic instead of supplying my own (that’ll be a topic for a later post).

As I said earlier, I want different ribbon additions in different windows, so the next thing to do is specialize Ribbon.GetCustomUI, the method which loads the ribbon XML at runtime. Change it to:

public string GetCustomUI(string ribbonID)
    if (ribbonID == "Microsoft.Outlook.Mail.Compose")
        return GetResourceText("NoReplyAddin.ComposeRibbon.xml");
       return null;

This loads our XML only for the composition window (used for new emails or forwarding and replying) – a list of all the ribbon ids can be found in, guess where, the MSDN – well, all the ids in Outlook 2007; Outlook 2010 adds a ribbon to the main window which has id Microsoft.Outlook.Explorer.

Now if you F5 and run, you’ll see our button on the end of the compose window ribbon (and on no other windows). You can click the button, toggling its state on and off, but it otherwise does nothing at all yet. We need to add some event handlers (this fact is mentioned, though somewhat cryptically, in the Ribbon.cs TODO comment too). Add the attribute onAction=“ComposeButton_Click” to the toggleButton XML element – this indicates that clicking the button will call the method ComposeButtonClick in whichever class provides the XML, i.e., the one which offers GetCustomUI, our Ribbon class in this case. Add the following method to that class:

public void ComposeButton_Click(Office.IRibbonControl control, bool pressed)

When you run this one, you’ll see we have a functioning (albeit not very useful) button. Incidentally, if you don’t see the “Click!” message box – or if you find that ribbon additions aren’t showing up where you expect them, a useful debugging tip is to check the “Show add-in user interface errors” box in Advanced Settings in Outlook. That’ll alert you to, for example, typos in the XML or missing event handlers.

That’ll do for today. Next time, I’ll examine the Outlook object model, so that we can write (and read) the no-reply-all state of an email, and thus can make the button do something worthwhile.

As well as the links already mentioned, a couple of good documents to read about ribbon customization are “Customizing the ribbon in Outlook 2007” and a detailed three part article on the Office ribbon, particularly the middle one which lists all of the ribbon XML elements.