Mysterious Errors When Using Form Regions from Managed Code Add-ins

I’ve been noticing some feedback lately where a number of developers were having problems working with the controls on their form region.  Usually, these problems manifested as Outlook’s object model returning null values back when trying to access the Controls collection of the UserForm object in the Microsoft Forms 2.0 library (which was accessed from the FormRegion.Form property).

This can be especially frustrating, because it looks like you’ve done everything right, and Outlook is just giving you back something that is totally wrong. Turns out, that isn’t quite the case.

If you’ve added a reference to the ‘Microsoft Forms 2.0’ type library, you might have added the wrong reference to your project. On some computers, you’ll find two different listings for the forms type library in the Add Reference dialog:

Depending on which reference you select, you’ll either get a reference properly associated with the Primary Interop Assembly provided by Office, or you’ll get a reference with a Visual Studio generated interop assembly. Unfortuatnely, the VS generated interop assembly incorrectly maps some elements of the type library to elements in the interop assembly.  This ultimately means that when you are using this reference, you’ll end up calling into a different property or method than your code appears to be calling, which causes various strange exceptions and errors.

You can easily determine which reference you are using by selecting the reference and looking at the properties of the reference. If you’ve added the self-generated IA reference, the properties will look like this:

Notice that the reference has “Copy Local” set to True, and that the Path is not pointing at the Global Assembly Cache (GAC) but rather to the location of my solution.  This indicates that I’m using a self-generated interop assembly, and that I may be running into issues.

If you’ve added the correct reference to the PIA, then you’ll see properties that look like this instead:

This time around, you’ll see the Path is pointing into the GAC, and the “Copy Local” property is False. This indicates the PIA is being used, and everything should work normally.

If you find your project is using the incorrect reference, you should remove the reference and add a new reference.  Unforutnately, there is no way to determine which reference is the “right” reference from the Add References dialog.  You’ll simply need to use trial and error and double check after adding the resource to make sure you’ve picked the right one.

The Take-away: Make sure you are using the right interop assembly when working with custom forms or form regions from your managed code solution.  Using the Visual Studio generated interop assembly can cause mysterious errors in your solution that you may not catch right away.

Comments (4)

  1. sgramesha says:

    I have been getting this problem even after setting the right reference to Microsoft Forms 2.0 library.

    I am using a ListBox control on my form region and want to get a handle to it in my form region code.

    I am doing something like below.

    public void BeforeFormRegionShow(Outlook.FormRegion FormRegion)


               this.FormRegion = FormRegion;

              this.FormRegion.SuppressControlReplacement = true;

               this.UserForm = FormRegion.Form as UserForm;

               Microsoft.Vbe.Interop.Forms.ListBox list1 = this.UserForm.Controls.Item("Notes") as Microsoft.Vbe.Interop.Forms.ListBox;

    But I am getting the value of list1 as null. Is there anything else that I am missing here ??



  2. rgregg says:


    I think you are using the wrong class for the ListBox. Although you set the property SuppressControlReplacement = true, if you added the control at design time, the control was replaced with the OlkListBox control.  Since you are using the "as" notation to do the type cast, if a type mismatch occurs, the value is set to null.

    In this case, you would need to use Outlook.OlkListBox as the type for the list box.  If you want to use the legacy Forms 2.0 ListBox, you would need to add the control at runtime using UserForm.Controls.Add(), after setting the SuppressControlReplacement property to true;

  3. Rama says:

    I am also working on similar lines.

    1)I have added a ListBox dynamically to a form region and trying to add multiple columns and items using set_Column(). I am using right version of dll as you specified in your above post.I have some questions:

    a) At runtime, It shows a single column with no items in it. multiple columns are not getting displayed.

    b) The items in the list are not getting displayed.

    c) There is not much documentation for these controls. Is there any sample code which shows adding multiple columns to a List Box in a form region dynamically?

    d) There are only limited number of controls supported in Outlook form region, so we don’t have much control to form regions. Can we add normal Windows.Forms controls to form region?  

    e) If your answer is VS 2008-Orcas, Could you please let me know when can we expect it to be released?


    my code is as follows:

           static string column= "Col1";

           static string value = "aaa1";

           static int index = 0;

           object objString = column;

           object objValue = value;

           object objIndex = index;

           static string column2= "Col2";

           static string value2 = "aaa2";

           static int index2 = 1;

           object objString2 = column2;

           object objValue2 = value2;

           object objIndex2 = index2;

    public void BeforeFormRegionShow(Outlook.FormRegion FormRegion)


    FormRegion.SuppressControlReplacement = true;

    Microsoft.Vbe.Interop.Forms.ListBox winformListBox = (Microsoft.Vbe.Interop.Forms.ListBox)UserForm.Controls.Add("Forms.ListBox.1", "winListBox", true);

    winformListBox.ColumnHeads = true;

    winformListBox.set_Column(ref objString1, ref objIndex1, ref objValue1);

    winformListBox.set_Column(ref objString2, ref objIndex2, ref objValue2);

    winformListBox.Enabled = true;

    winformListBox.AddItem(ref objValue1, ref objIndex1);





  4. WellsZhang says:

    As you said, I have tried the interface Outlook._FormRegionStartup. But it always can’t invoke the method public void BeforeFormRegionShow(Outlook.FormRegion FormRegion).

    I don’t konw what’s reason.