Pieter van der Westhuizen

Creating Outlook ribbon UI from scratch – Integrating with Freshbooks web-service, part 3

In part one of the series, we’ve created Freshbooks specific folders, set their Message classes and created a Freshbooks Solution Module. In part two we continued by adding custom properties to the folders and created custom views. We’ve also replaced the Outlook Inspector UI with our own and imported Freshbooks data into Outlook.

In this article, we’ll continue with the add-in and tackle the process of hiding the standard Outlook Inspector and Explorer Ribbon tabs for the Freshbooks folders and items and replacing them with our own Freshbooks Ribbon Tabs. At the end of this article, we’ll accomplish what the following image illustrates in Outlook:

Building Outlook ribbon from scratch for Explorer and Inspector windows

Replacing the built-in Outlook Inspector ribbon with a custom one

First, we need to hide the built-in Inspector ribbon tabs for any Outlook Inspector object that contains an item with a Message Class of IPM.Contact.Freshbooks.Project.

To do this, we’ll add an ADXRibbonTab control for each Ribbon Tab that needs to be hidden. We’ll need to set the IdMso property for each tab as well as set the Ribbons property to OutlookContact. There needs to be 7 ADXRibbonTab controls in total, each with the following values for their respective IdMso properties:

  • TabContact
  • TabInsert
  • TabReviewWord
  • TabFormatText
  • TabDeveloper
  • TabAddIns
  • TabBackgroundRemoval
Note, that we do not set the Visible property to False at this stage. This will cause the Ribbon tabs to be hidden for all Outlook Contact inspectors. We’ll hide the ribbons in code.

Switch to the code view of the AddinModule and add the following local variable:

private IRibbonUI theRibbonUI;

Next, add a method called InvalidateControls. This method will invalidate all the Ribbon Tab controls we’ve added earlier. This is done by invoking the InvalidateControl for each control. The code for the method follows below:

private void InvalidateControls()
{
    if (theRibbonUI != null)
    {
		//Standard Contact Inspector Tabs
		theRibbonUI.InvalidateControl("contactInspector_ContactRibbonTab_eea98e2c4ad84d2a93a05c6f5c9170dd");
		theRibbonUI.InvalidateControl("contactInspector_InsertRibbonTab_5aa0162c5a7c4c94b04e666fe7b6efa7");
		theRibbonUI.InvalidateControl("contactInspector_FormatTextRibbonTab_e7b8bd77dd864d4ba50f40f17c3a0136");
		theRibbonUI.InvalidateControl("contactInspector_ReviewRibbonTab_f348065ef6b94f028cefb902ac5fa622");
		theRibbonUI.InvalidateControl("contactInspector_DeveloperRibbonTab_db566a3b1760414a97bf6e4f8878b7e1");
		theRibbonUI.InvalidateControl("contactInspector_AddinsRibbonTab_e45f76267d5d411b8172788fed610b6a");
		theRibbonUI.InvalidateControl("contactInspector_BackgroundRemovalRibbonTab_91b3a84c83174c2bb1df63c23827287b");
		theRibbonUI.InvalidateControl("contactInspector_DealRibbonTab_68fe916c0442489b922312283a811050");
    }
}

Switch back to the AddinModule designer surface and add a new ADXRibbonTab control. This Ribbon Tab will contain the Freshbooks Project specific tasks and will be the only Ribbon Tab that is visible on the Inspector window. The design of your custom Ribbon Tab could resemble the following image:

The design of a custom Outlook Ribbon Tab for the Inspector window

Also add a new Outlook Events component to the AddinModule designer surface and create an event handler for the InspectorActivate event. Add the following code to the event handler:

private void adxOutlookEvents_InspectorActivate(object sender, object inspector, string folderName)
{
    Outlook.Inspector currInspector = null;
    Outlook.ContactItem contact = null;
    object currItem = null;
 
    try
    {
        currInspector = (Outlook.Inspector)inspector;
        currItem = currInspector.CurrentItem;
 
        if (currItem is Outlook.ContactItem)
        {
            contact = currItem as Outlook.ContactItem;
            if (contact.MessageClass.Contains("IPM.Contact.Freshbooks.Project"))
            {
                contactInspector_ContactRibbonTab.Visible = false;
                contactInspector_InsertRibbonTab.Visible = false;
                contactInspector_FormatTextRibbonTab.Visible = false;
                contactInspector_ReviewRibbonTab.Visible = false;
                contactInspector_DeveloperRibbonTab.Visible = false;
                contactInspector_AddinsRibbonTab.Visible = false;
                contactInspector_BackgroundRemovalRibbonTab.Visible = false;
            }
            else
            {
                InvalidateControls();
                contactInspector_ContactRibbonTab.Visible = true;
                contactInspector_InsertRibbonTab.Visible = true;
                contactInspector_FormatTextRibbonTab.Visible = true;
                contactInspector_ReviewRibbonTab.Visible = true;
                contactInspector_DeveloperRibbonTab.Visible = true;
                contactInspector_AddinsRibbonTab.Visible = true;
                contactInspector_BackgroundRemovalRibbonTab.Visible = true;
                InvalidateControls();
 
                adxProjectsInspectorRibbonTab.Visible = false;
            }
        }
    }
    finally
    {
        if (currItem != null) Marshal.ReleaseComObject(currItem);
        if (currInspector != null) Marshal.ReleaseComObject(currInspector);
    }
}

In the code above, we first checked whether the item that is currently open in the Outlook Inspector’s MessageClass, property is IPM.Contact.Freshbooks.Project. If it is, we hid all the built-in Outlook Contact Inspector Ribbon tabs and only shown our custom Ribbon Tab. If the MessageClass is not the same as the Freshbooks Project’s MessageClass, we did the reverse, by showing the built-in Ribbon Tabs and hiding our own. Finally, we called the InvalidateControls method.

How to add custom icons to Outlook folders and ribbon controls

You might have noticed that we’re using custom icons for our Ribbon Tabs and Solution Module folders. Add-in Express makes it very easy to use your own icons for both the Solution Module folders as well as the Explorer ribbon tab. To use your own icons for your custom Outlook Ribbon Tab, first add a standard ImageList control to the AddinModule designer surface.

Adding a standard ImageList control to the AddinModule designer surface.

If you’re planning on using the ImageList for displaying the Solution Module folder icons or for Outlook Ribbon buttons, whose Size property is set to Regular, set the ImageList’s ImageSize property to 16×16. If you want to use the icons on large Ribbon buttons set the ImageSize to 32×32. Also, to make sure the image looks good inside the Ribbon button or Solution Module, set its ColorDepth property to Depth32Bit.

For the image to look good inside the Ribbon button, set the image ColorDepth property to Depth32Bit.

To set the Outlook Ribbon buttons’ icon, select the ImageList’s name in the button’s ImageList property and select the image to display in its Image property. The same procedure applies for setting folder icons for the Solution Module.

Setting up the icon for Outlook Ribbon buttons

The icons we’re using for this example was generated using <atarget=_blank href=”https://www.syncfusion.com/downloads/metrostudio”>Syncfusion Metro Studio – a collection of over 2500 Metro-style icons.

Customizing the Outlook Explorer ribbon UI from scratch

The next task in our list is to hide the built-in Contact Explorer Ribbon Tabs for our Freshbooks Projects folder and only show our own Ribbon Tab. First, we’ll need to add a new ADXRibbonTab to the AddinModule designer surface. This Ribbon Tab will be visible for any Freshbooks Projects folders in the Outlook Explorer.

The design of your custom Outlook Ribbon Tab should look similar to the following image:

The design of your custom Outlook Ribbon Tab

Now, set its Caption Property to PROJECTS and the Ribbons property to OutlookExplorer. Next, similar to what we’ve done for the Outlook Inspector Ribbon Tab, we’ll need to add an ADXRibbonTab component for each Outlook Explorer RibbonTab we need to hide. There are 9 built-in Ribbon Tabs we need to hide. Set the Ribbons property to OutlookExplorer for each of them and set their IdMso properties to the following:

  • TabSendReceive
  • TabFolder
  • TabTasks
  • TabView
  • TabDeveloper
  • TabMail
  • TabContacts
  • TabAddIns
  • TabJournals

Again, we should not set the Visible property to false in this case.

We’ll reuse the InvalidateControls method to invalidate any Explorer controls as well. Update the InvalidateControls method to the following:

private void InvalidateControls()
{
    if (theRibbonUI != null)
    {
        theRibbonUI.InvalidateControl("adxRibbonTab_b3e50cf211904199836f12db0951c596");
 
        // Standard Contact Explorer Tabs
        theRibbonUI.InvalidateControl("Explorer_TaskHomeRibbonTab");
        theRibbonUI.InvalidateControl("Explorer_HomeRibbonTab_b1b0c24f21d64a2698833e0bdcd5f4f3");
        theRibbonUI.InvalidateControl("Explorer_SendReceiveRibbonTab_1f502540e12347fca75243b1d110a47c");
        theRibbonUI.InvalidateControl("Explorer_FolderRibbonTab_8073e13915c240d59a2390e9921ec3d5");
        theRibbonUI.InvalidateControl("Explorer_ViewRibbonTab_b3538d30fb984f068d76a3d3c8435ea7");
        theRibbonUI.InvalidateControl("Explorer_DeveloperRibbonTab_2a9ec8d1e6604b10acf62c20f1add267");
        theRibbonUI.InvalidateControl("Explorer_AddinsRibbonTab_de8bf649786d4405983c130c527f1079");
 
        //Standard Contact Inspector Tabs
        theRibbonUI.InvalidateControl("contactInspector_ContactRibbonTab_eea98e2c4ad84d2a93a05c6f5c9170dd");
        theRibbonUI.InvalidateControl("contactInspector_InsertRibbonTab_5aa0162c5a7c4c94b04e666fe7b6efa7");
        theRibbonUI.InvalidateControl("contactInspector_FormatTextRibbonTab_e7b8bd77dd864d4ba50f40f17c3a0136");
        theRibbonUI.InvalidateControl("contactInspector_ReviewRibbonTab_f348065ef6b94f028cefb902ac5fa622");
        theRibbonUI.InvalidateControl("contactInspector_DeveloperRibbonTab_db566a3b1760414a97bf6e4f8878b7e1");
        theRibbonUI.InvalidateControl("contactInspector_AddinsRibbonTab_e45f76267d5d411b8172788fed610b6a");
        theRibbonUI.InvalidateControl("contactInspector_BackgroundRemovalRibbonTab_91b3a84c83174c2bb1df63c23827287b");
        theRibbonUI.InvalidateControl("contactInspector_DealRibbonTab_68fe916c0442489b922312283a811050");
    }
}

In order to hide or show the correct Explorer Ribbon Tabs, we’ll need to add logic to the ExplorerFolderSwitch Outlook event. To do this, select the Outlook Events component we’ve added earlier and double-click next to the ExplorerFolderSwitch event in its event list.

Adding logic to the ExplorerFolderSwitch Outlook event

Add the following code to the ExplorerFolderSwitch event handler:

private void adxOutlookEvents_ExplorerFolderSwitch(object sender, object explorer)
{
    Outlook.Explorer currExplorer = null;
    Outlook.Folder folder = null;
    Outlook.Folder parentFolder = null;
 
    try
    {
        currExplorer = (Outlook.Explorer)explorer;
        folder = (Outlook.Folder)currExplorer.CurrentFolder;
        if (folder.Parent is Outlook.Folder)
            parentFolder = folder.Parent as Outlook.Folder;
 
        bool show = !parentFolder.Name.Contains("Freshbooks");
        Explorer_HomeRibbonTab.Visible = show;
        Explorer_SendReceiveRibbonTab.Visible = show;
        Explorer_FolderRibbonTab.Visible = show;
        Explorer_ViewRibbonTab.Visible = show;
        Explorer_DeveloperRibbonTab.Visible = show;
        Explorer_AddinsRibbonTab.Visible = show;
        Explorer_TaskHomeRibbonTab.Visible = show;
        Explorer_JournalHomeRibbonTab.Visible = show;
        Explorer_MailHomeRibbonTab.Visible = show;
 
        if (parentFolder.Name == "Freshbooks" && folder.Name == "Projects")
        {
            SetView(folder, "Freshbooks Projects");
            adxFreshbooksProjectsExplorerRibbonTab.Visible = true;
        }
        else
        {
            adxFreshbooksProjectsExplorerRibbonTab.Visible = false;
        }
 
        if (parentFolder.Name == "Freshbooks" && folder.Name == "Clients")
        {
            SetView(folder, "Freshbooks Clients");
        }
 
        InvalidateControls();
    }
    finally
    {
        if (folder != null) Marshal.ReleaseComObject(folder);
        if (parentFolder != null) Marshal.ReleaseComObject(parentFolder);
    }
}

In the preceding code, we checked whether the current folder is a Freshbooks folder, and then hid or shown the built-in Outlook Explorer Ribbon Tabs. We then hid or shown the individual Freshbooks specific Ribbon Tab and set the current view using the SetView method. The code for the SetView method follows below:

private void adxOutlookEvents_ExplorerFolderSwitch(object sender, object explorer)
{
    Outlook.Explorer currExplorer = null;
    Outlook.Folder folder = null;
    Outlook.Folder parentFolder = null;
 
    try
    {
        currExplorer = (Outlook.Explorer)explorer;
        folder = (Outlook.Folder)currExplorer.CurrentFolder;
        if (folder.Parent is Outlook.Folder)
            parentFolder = folder.Parent as Outlook.Folder;
 
        bool show = !parentFolder.Name.Contains("Freshbooks");
        Explorer_HomeRibbonTab.Visible = show;
        Explorer_SendReceiveRibbonTab.Visible = show;
        Explorer_FolderRibbonTab.Visible = show;
        Explorer_ViewRibbonTab.Visible = show;
        Explorer_DeveloperRibbonTab.Visible = show;
        Explorer_AddinsRibbonTab.Visible = show;
        Explorer_TaskHomeRibbonTab.Visible = show;
        Explorer_JournalHomeRibbonTab.Visible = show;
        Explorer_MailHomeRibbonTab.Visible = show;
 
        if (parentFolder.Name == "Freshbooks" && folder.Name == "Projects")
        {
            SetView(folder, "Freshbooks Projects");
            adxFreshbooksProjectsExplorerRibbonTab.Visible = true;
        }
        else
        {
            adxFreshbooksProjectsExplorerRibbonTab.Visible = false;
        }
 
        if (parentFolder.Name == "Freshbooks" && folder.Name == "Clients")
        {
            SetView(folder, "Freshbooks Clients");
        }
 
        InvalidateControls();
    }
    finally
    {
        if (folder != null) Marshal.ReleaseComObject(folder);
        if (parentFolder != null) Marshal.ReleaseComObject(parentFolder);
    }
}

At this point, you can build, register and run your project and you should see the Freshbooks specific Ribbon Tabs when selecting the Projects folder in the Freshbooks Solution module. You should also see the Freshbooks Inspector Ribbon Tab when creating or opening a Freshbooks Project item in Outlook.

When switching to a standard Outlook Contacts folder, the Freshbooks specific Ribbon Tab should no longer be visible, and you should see the standard Outlook Contact Inspector or Explorer Ribbons.

Thank you for reading. Until next time, keep coding!

Available downloads:

This sample Outlook add-in was developed using Add-in Express for Office and .net:

Freshbooks Outlook add-in (C#)

How to integrate Outlook add-in with the Freshbooks web-service

Post a comment

Have any questions? Ask us right now!