Pieter van der Westhuizen

HowTo: Replace the standard Outlook Task UI

Add-in Express for Office and .net version 6.4, introduced us to the CompleteReplacement Outlook form region in March this year. With this region you are able to completely replace the entire area of an Outlook Inspector.

When I first saw this region I was perplexed as to why you would ever need it, that is until I realized this new region gives Office developers an exciting new way to add our own logic to Outlook or even replace Outlook’s logic. For example, a client asks you to write an Outlook add-in that will replace the standard Outlook task functionality with their own in-house task tracking systems. The client would still like to see all their tasks in Outlook, but all information regarding the tasks need to be saved to an external system.

With Add-in Express for Office and .net in our toolbox, let’s tackle this challenge head on!

First we need to create a new COM Add-in project in Visual Studio.

Creating a new add-in project

In the New Microsoft Office COM Add-in wizard select your programming language and the Minimum Office version you would like to support. We’ll be using Visual C# and Microsoft Office 2010 as the minimum supported Office version. Also, choose Microsoft Outlook as the supported application.

After finishing the wizard, add a new ADX Outlook Form to your project by choosing Add New Item… from the Visual Studio Project menu.

Adding a new Outlook Form to your project

Customize the new ADX Outlook Form to resemble the following image.

Customizing the new Outlook form

Next, switch to the AddinModule designer and add a new ADXOlFormsManager. Add a new item to its Items collection and set its properties to the following:

  • InspectorItemTypes : Task
  • InspectorLayout: CompleteReplacement
  • FormClassName: CompleteReplacementRegionDemo.customTaskForm

Build, register and run your project. In Outlook create a new task. You should see your ADX Outlook Form instead of the standard Outlook Task UI.

At this stage, we have our own custom task UI, but we still need to add our own functionality and logic. For one, we need to remove some of the ribbon tabs and buttons from the Outlook task form and add our own logic behind the Save button.

We will not require the Insert, Format Text and Review ribbon tabs, so in order to remove them, add three ADXRibbonTab components to the AddinModule designer and set their properties to the following:

Insert Ribbon tab

  • Name: insertRibbonTab
  • IdMso: TabInsert
  • Ribbons: OutlookTask
  • Visible: False

Format Text Ribbon tab

  • Name: formatTextRibbonTab
  • IdMso: TabFormatText
  • Ribbons: OutlookTask
  • Visible: False

Review tab

  • Name: reviewRibbonTab
  • IdMso: TabReviewWord
  • Ribbons: OutlookTask
  • Visible: False

We also won’t require the Show, Manage Task, Recurrence, Tags and Zoom ribbon groups. To remove them add another ADXRibbonTab component to the AddinModule designer and set its IdMso property to TabTask and its Ribbons property to OutlookTask. Add five Ribbon group controls to the new Ribbon Tab and set their properties to:

Manage Task Ribbon group

  • Name: manageTaskRibbonGroup
  • Caption: Manage Task
  • IdMso: GroupManageTask
  • Visible: False

Show Ribbon group

  • Name: showRibbonGroup
  • Caption: Show
  • IdMso: GroupShow
  • Visible: False

Recurrence Ribbon group

  • Name: recurrenceRibbonGroup
  • Caption: Recurrence
  • IdMso: GroupRecurrence
  • Visible: False

Tags Ribbon group

  • Name: tagsRibbonGroup
  • Caption: Tags
  • IdMso: GroupTaskOptions
  • Visible: False

Zoom Ribbon group

  • Name: zoomRibbonGroup
  • Caption: Zoom
  • IdMso: GroupZoom
  • Visible: False

With the above mentioned ribbon groups removed, we only have the Actions ribbon group left. We want to give our users the ability to save and complete tasks, so we need to remove all the buttons except for the Save & Close and Mark Complete buttons. To do this, add another Ribbon group to our Task ribbon tab, and set its properties to:

Actions Ribbon group

  • Name: actionsRibbonGroup
  • Caption: Actions
  • IdMso: GroupActions
  • Visible: False

Add another Ribbon group and set its Caption property to New Task System Actions. Next, add two Ribbon buttons to the group and set their properties to:

Save & Close button

  • Name: saveCloseRibbonButton
  • Caption: Save && Close
  • IdMso: SaveAndClose
  • Size: Large

Mark Complete button

  • Name: markCompleteRibbonButton
  • Caption: Mark Complete
  • IdMso: MarkTaskComplete
  • Size: Large

When clicking on our newly added buttons, it will trigger the standard, save and complete task actions in Outlook. We’ve done this by setting the buttons’ IdMso property to the corresponding built-in Outlook buttons’ name. We need to perform our own logic before the task is saved or completed in Outlook, to do this, add two new ADXRibbonCommand components to the AddinModule designer. Set their properties to the following:

Save & Close Ribbon Button Command

  • Name: saveAndCloseRibbonCommand
  • ActionTarget: Button
  • IdMso: SaveAndClose
  • Ribbons: OutlookTask

Mark Completed Ribbon Button Command

  • Name: markCompletedRibbonCommand
  • ActionTarget: Button
  • IdMso: MarkTaskComplete
  • Ribbons: OutlookTask

Add the following code to the Save and Close ribbon command OnAction event handler:

private void saveAndCloseRibbonCommand_OnAction(object sender, IRibbonControl control, bool pressed, ADXCancelEventArgs e)
{
    customTaskForm taskform = (customTaskForm)adxOlFormsCollectionItem1.GetCurrentForm(AddinExpress.OL.EmbeddedFormStates.Visible);
 
    if (taskform != null)
    {
        Outlook.Inspector currInspector = null;
        Outlook.TaskItem currTask = null;
        Outlook.UserProperties userProperties = null;
        Outlook.UserProperty rateProperty = null;
        Outlook.UserProperty customerNameProperty = null;
        object currItem = null;
 
        try
        {
            currInspector = OutlookApp.ActiveInspector();
            currItem = currInspector.CurrentItem;
 
            if (currItem is Outlook.TaskItem)
            {
                currTask = (Outlook.TaskItem)currItem;
                currTask.Subject = taskform.txtTaskName.Text;
                currTask.Body = taskform.txtDescription.Text;
                currTask.DueDate = taskform.dtpDue.Value;
 
                userProperties = currTask.UserProperties;
                customerNameProperty = userProperties.Find("CustomerName");
                if (customerNameProperty == null)
                {
                    customerNameProperty = userProperties.Add("CustomerName", Outlook.OlUserPropertyType.olText, true);
                }
                customerNameProperty.Value = taskform.txtCustomerName.Text;
 
                rateProperty = userProperties.Find("RatePH");
                if (rateProperty == null)
                {
                    rateProperty = userProperties.Add("RatePH", Outlook.OlUserPropertyType.olNumber, true);
                }
                rateProperty.Value = taskform.txtRate.Text;
            }
 
            SaveInfoToCustomTaskTrackingSystem();
 
        }
        finally
        {
            if (customerNameProperty != null)
                Marshal.ReleaseComObject(customerNameProperty);
            if (rateProperty != null)
                Marshal.ReleaseComObject(rateProperty);
            if (userProperties != null)
                Marshal.ReleaseComObject(userProperties);
            if (currItem != null)
                Marshal.ReleaseComObject(currItem);
            if (currInspector != null)
                Marshal.ReleaseComObject(currInspector);
        }
    }
}

The code above will save some information to Outlook, and the rest to our custom task tracking database. In order to do the same when the task is completed add the following code to the Mark Completed OnAction event handler:

private void markCompletedRibbonCommand_OnAction(object sender, IRibbonControl control, bool pressed, ADXCancelEventArgs e)
{
    Outlook.Inspector currInspector = null;
    Outlook.TaskItem currTask = null;
    object currItem = null;
 
    try
    {
        currInspector = OutlookApp.ActiveInspector();
        currItem = currInspector.CurrentItem;
        if (currItem is Outlook.TaskItem)
        {
            currTask = (Outlook.TaskItem)currItem;
            currTask.MarkComplete();
            SaveCompletedTaskToCustomTrackingSystem();
        }
 
    }
    finally
    {
        if (currItem != null)
            Marshal.ReleaseComObject(currItem);
        if (currInspector != null)
            Marshal.ReleaseComObject(currInspector);
    }
}

This code will mark the task as completed in Outlook as well as in our custom tracking system. Our completed custom task UI would look similar to the following image:

Custom Outlook task UI

For a list of all the built-in Office controls and their IDs: Office 2007 control IDs and Office 2010 control IDs.

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

Available downloads:

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

You may also be interested in:

Extend Outlook UI with advanced version neutral regions
How to build and control advanced Outlook regions

2 Comments

  • Mehnaz Anwar says:

    I have add-in-express 2010 for office and vsto, so for complete replacement technique you described ,it gives template ADX for VSTO Addin, well if I choose it , it gives me minimum supported version office 2007.

    Now if I take it and set the target application .net framework to 3 instead of 3.5 or 4, it says that the project type you selected does not support .net framework 3.0.

    My question is – is it true for also the above example you gave. or it will work for .net frame work less than 3 and will will work on outlook 2007/2010 32 bit/64bit.

  • Pieter van der Westhuizen says:

    Hi Mehnaz,

    If you’re using Visual Studio 2010 and VSTO you can only create add-in for office 2007-2010. Please refer to this MSDN article: https://msdn.microsoft.com/en-us/library/bb772080.aspx
    The example in this blog post was written using Add-in Express for Office and .net in Visual Studio 2010. It should work with .Net framework 2 to 4 as well as on Outlook 2007 and 2010(32 and 64 bit)

    Hope this answered your question.

Post a comment

Have any questions? Ask us right now!