Welcome to X4U
Minimize 

Hello visitor.

This is the personal homepage of Helmut Obertanner.
I'm a computer freak and electronic enthusiast and I live in Munich in Germany - the hometown of the famous Oktoberfest.
Why the name X4U? In my case it's a synonym for everything is possible.
I'm an experienced full time C# developer and doing so since .Net Framework 1.0.
As technical enthusiast I started Office development using .Net technologies.
As I searched answers and found help in the Internet I decided to share my knowledge in newsgroups and forums too. For participation, helping other developers, writing how-to's and articles and doing consulting and trainings I received the Microsoft MVP Award for the 3rd time.

As Outlook C# specialist I founded the website Outlooksharp.de
Beside software development, I'm building electronic devices for customers.
Prototypes with SMD PCBs and complete electronic devices with USB connections are my typical portfolio.
You got an Idea and have no plan how to put it to work - give me a call and I tell you if I can help.
A complete solution starts from defining the requirements, design the schematic and PCB, build a functional prototype, program the firmware, program the windows software, design and build a housing prototype.
Usually I work with very cheap PIC 18F Microcontrollers, these multifunctional devices are programmed in C language. 

I'm located in Germany with satisfied customers around the globe.
Enjoy the content of my site and feel free to give me your feedback.
You're welcome.
X4U Blog
 
Jun29

Written by:Helmut Obertanner
6/29/2009 10:02 PM 

How to programmatically select a custom Form Region

Hello, in this Article let me show you how to create a Custom Form Region, a Ribbon button and displaying this Form when you click on it.
For this demo we are extending the standard Outlook Contact Form.
First we need to create a VSTO Project – let's give it the Name "SwitchFormPage":

Picture 1: Create a VSTO Outlook Add-in project

After you finished the project wizard you can add a custom Form Region to the project.
Just right-click the project and add a new Item. In the "Add New Item" dialog, select "Outlook Form Region".

Picture 2: Adding a custom Form Region to the project

Let's give it the name "ContactInfo". In the following wizard, you can choose between two options:

A: Design a new form region – create it from scratch within Visual Studio using .Net Controls.
B: Import an Outlook Form Storage (.ofs) file. This means you can design a custom form region using the Outlook embedded form designer and save that as ".ofs" file, and import it here into visual Studio.

We create our form from scratch so let's choose A.

Picture 3: Choose how you want to create your form region

Now you can select the type of the form you want to add. In this sample I want to demonstrate how to switch between forms and form regions, so we create a separate form region.
The Wizard is self-explanatory. On the Wizard select "Separate".

Picture 4: Select the form region type

On the next screen you give the form region a descriptive text and select if the form region will be visible compose and/or in read mode.

Picture 5: Description and display options

The next screen defines on what forms this form region will be visible.
You can choose between the standard forms, and define custom message classes where the form should appear.
I want the form region to show up on the default contact form so I select only "Contact (IPM.Contact)". "IPM.Contact" is the Outlook internal prefix used to identify a "ContactItem" – also called "MessageClass". Every Item in Outlook has a "MessageClass" property. In General there are different ways to check the type of an Item. You can use the Is Operator, the As Statement or check the "MessageClass" of an Item using late binding if the type is not enough – e.g. when you have custom message classes.
Why do I need this?
Since all Items are internally messages, you need a way to differentiate between the item types.
In many functions you will only get an object as Item type.
Let's have a look at the Application.Item_Send event. You can send out different Items (Emails, Meeting-Requests/Responses, Delivery-Reports, etc.).
Here is method A:

///<summary>

/// Eventhandler for the Item_Send event.

/// Is raised whenever an Item is sent out.

///</summary>

///<param name="Item">The Item that is sent.</param>

///<param name="Cancel">Set Cancel to true to interrupt the send process for the Item</param>

void Application_ItemSend(object Item, refbool Cancel) {

 

if (Item is Outlook.MailItem) {

// Email

// Cast to EmailItem

Outlook.MailItem mail = (Outlook.MailItem)Item;

// ...

 

} elseif (Item is Outlook.MeetingItem) {

// Meting

// Cast to MeetingItem

Outlook.MeetingItem mail = (Outlook.MeetingItem)Item;

// ....

}

}
Listing 1: Using the is operator to determine the Item type.

///<summary>

/// Eventhandler for the Item_Send event.

/// Is raised whenever an Item is sent out.

///</summary>

///<param name="Item">The Item that is sent.</param>

///<param name="Cancel">Set Cancel to true to interrupt the send process for the Item</param>

void Application_ItemSend(object Item, refbool Cancel) {

 

// best, when you only test fo a single type

Outlook.MailItem mail = Item as Outlook.MailItem;

if (mail != null) {

 

// we got it

// ...

}

}

Listing 2: Use the as Operator if you only want to test for a single type.

///<summary>

/// Eventhandler for the Item_Send event.

/// Is raised whenever an Item is sent out.

///</summary>

///<param name="Item">The Item that is sent.</param>

///<param name="Cancel">Set Cancel to true to interrupt the send process for the Item</param>

void Application_ItemSend(object Item, refbool Cancel) {

 

// Read the MessageClass property of the Item using late binding

string messageClass = (string)Item.GetType().InvokeMember("MessageClass", BindingFlags.GetProperty, null, Item, null);

 

switch (messageClass) {

 

case"IPM.Post":

 

Outlook.MailItem mail = (Outlook.MailItem)Item;

// ... do something

 

break;

 

case"IPM.Post.CustomMessageClass":

 

Outlook.MailItem customMail = (Outlook.MailItem)Item;

// ... do something other stuff

 

 

break;

}

}

Listing 3: Reading the MessageClass property using late binding

Choose the best option depending on your use case. A small excursion about message classes. But now back to the form page.
When you finished the form page wizard, you fill find a new user control in your project that represents the custom form region.
You can design it as you like using the Visual Studio Designer. Just double-click it and add some controls on it.
In my case I added a Splitter, a ListView on Panle1 and a WebBrowser on Panel2.

Picture 6: Design a form region like a user control in visual studio

When you designed your Form, you can start debugging by pressing "F5" and when you create a new or open an existing contact,
you may notice that your custom form region appears as extra Item within the Ribbon.
When you click on the "Contact Information" entry, you will see your form region in the contact form.

Picture 7: The custom form region is visible after you clicked the menu entry.

Next, we want to extend the Ribbon and create a custom button that displays our form region when clicked. Again we need to add a new Item to the project.
In the "Add New Item" dialog select "Ribbon (Visual Designer)". I called it "ContactFormRibbon".

Picture 8: Adding a Ribbon to the project

The Ribbon has Special Menus, Tabs, Groups and Controls. I want to have an extra group called "X4U" with a king size button on it. On the contact form normally you have three tabs: "Contact", "Insert" and "Format Text".
I want to display my group on the left outer side of the "Contact" tab.

First set the Item type, where the Ribbon should be modified. You can do it by clicking on the Ribbon itself.

Picture 9: Click on the Ribbon container and choose the Item types to be modified

Then click at the Tab and change the settings as you can see on the next screen.
Change "Label" to "Contact", "Name" to "TabContact", "ControlIdType" to "Office" and "OfficeId" to "TabContact".

Picture 10: Modify the ControlId settings of the tab container.

You may ask: Where do I know the Office Id's ?
Answer: You can download it from Microsoft as Excel file. It's called Office Ribbon Ids.

http://www.microsoft.com/downloads/details.aspx?familyid=4329D9E9-4D11-46A5-898D-23E4F331E9AE&displaylang=en

Next we modify the group so that it shows up before the group named "Actions".
The important things here are "PositionType" it should be altered to "BeforeOfficeId" and "OfficeId" – it must be changed to "GroupActions".

Picture 11: Settings for the group container

The properties of the button I added to the Ribbon using the designer are not so important. You can give him a name and when you double-click the button, an event-handler stub is generated in the code behind file for the Ribbon.
And here is the most important part that demonstrated how to display a specific page when you click the button.

privatevoid buttonShowInfo_Click(object sender, RibbonControlEventArgs e) {

// Access the current Inspector Object

Outlook.Inspector inspector = this.Context as Outlook.Inspector;

 

// Set the Custom Form Region as current page

// Important: use the full qualified name of the class here

// namespace.classname

inspector.SetCurrentFormPage("SwitchFormPage.ContactInfo");

// release inspector objects immediatly

inspector = null;

}

Listing 4: The button click event handler

Important is the name you are using. It must be the full class name of the custom form region. In my case the form region is named "ContactInfo" and the namespace is "SwitchFormPage".
Just press "F5" to debug and it works as expected.

Picture 12: The new Ribbon button in the left corner

After clicking the button you will see your custom form page.

Picture 13: Click on the button changes the current form page

I hope that will help you VSTO guys out there.
If I find some time – I will make the solution available as download.


Greets - Helmut

Tags:

12 comment(s) so far...

Re: How to programmatically select a custom Form Region

I have a different requirement

I have to display my custom form region when we double click on a contact record.

By default it shows general

I am using this code to do so

Inspector.setCurrentFormPage("page Name");

But This not working

can you please help me in this matter

By chandresh tekchandani on  8/19/2009 5:12 PM

Re: How to programmatically select a custom Form Region

Hi chandresh,
what is the full qualified name of your custom Form? -> namespace.Formname
Have you tried this ?

Greets - Helmut

By Helmut Obertanner on  8/19/2009 5:14 PM

Re: How to programmatically select a custom Form Region

I have changed the code this way

contactItem = (Outlook.ContactItem)Inspector.CurrentItem;
contactItem.Open += new Microsoft.Office.Interop.Outlook.ItemEvents_10_OpenEventHandler(contactItem_Open);
try
{
Inspector.SetCurrentFormPage("OutlookAddIn_test_Custom.FormRegion2");
Inspector.Display(true);
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show(ex.Message);
}

this gives me an exception

The Specific page does not exist or not allow that operation

do you have any alternative of that

By Chandresh on  8/19/2009 7:00 PM

Re: How to programmatically select a custom Form Region

Hi chandresh,
this looks strange.
I belive your code is called within the NewInspector event. Am I right?

Then you say Inspector.Display(true)

This will show an Inspector as Modal Window.
If you like pass me over your solution as.zip to flash [at] x4u [dot] de
So I can have a look and see what's the problem.

Greets - Helmut

By Helmut Obertanner on  8/19/2009 7:05 PM

Re: How to programmatically select a custom Form Region

Hello Helmut,

I have attached a zip copy of my test application and sent to you please have a look on that.

By Chandresh Tekchandani on  8/20/2009 11:14 AM

Re: How to programmatically select a custom Form Region

Hello Helmut,

Thank You For Your solution it wroked Fine.

And even I have learned a lot from that.

Code Optimization is very good at there.

Regards,

Chandresh Tekchandani

By Chandresh Tekchandani on  8/21/2009 3:06 PM

Re: How to programmatically select a custom Form Region

Hi, just a quick question for you, is there anyway to hide the form region that automatically shows up on the ribbon ?

actually i just want to showup the form region when called from my own ribbon group.

as in your case, you can call the form region from your own custom ribbon group ( Show Info button of X4U ribbon group) and a button also appears on the "Show" ribbon group, i want to hide that "Contact Information" button appearing at "Show" ribbon group.


thanks :))

cheers

By SKhan on  10/27/2009 7:16 PM

Re: How to programmatically select a custom Form Region

Hi Helmut

Would it be possible that you show the solution here? I have a similar problem with a form region, I want to show on startup for existing appointments having a special ItemPropery.

Thanks in advance,
Martin

By Martin on  10/27/2009 7:16 PM

Re: How to programmatically select a custom Form Region

Hello SKhan,

basically (as far as I know) there is no standard way to archive this. But I will try to find a solution and if I find one. I would try to access the Ribbon by code, find the Button and set visible to false.

Hello Martin,
so let me clear - as I understand - you want to show your custom Formregion as default - if your appointment has a special property set.
You need to implement an InspectorWrapper code. Here you can set the initial FormPage.
I will write a small HowTo and post it here on my Blog.

Greets - Helmut

By Helmut Obertanner on  10/27/2009 7:29 PM

Re: How to programmatically select a custom Form Region

Thank you for this article Helmut.

Can I ask - is it possible to programatically collapse and expand a form bottom region?
I know the user can click on the small expand/collapse button on the corner but I'd like to give them the option of doing this with a large button on the ribbon.
I can't find the method on the formbottom to collapse/expand, only hide which makes the controls invisible but doesn't collapse the region allocated to it.
thanks

By Joel on  12/8/2009 3:03 PM

Re: How to programmatically select a custom Form Region

Excellent article, very useful for me, thanks Helmut.

Was the solution for how to "hide the form region that automatically shows up on the ribbon" ever achieved or posted somewhere? I find myself in the same situation, wanting to hide the one automatically added to the Show group, and have my own group and button that displays the form region instead. Using VS2008 VSTO Outlook 2007 VB. Customizing the Meeting form.

In the generated MyFormRegionFactory_FormRegionInitializing() function, there is a comment that says "To prevent the form region from appearing, set e.Cancel to true". When I do this it indeed does not display the form region icon that automatically shows up in the Show group of the ribbon. However, when I click my button and run the following code:

Dim inspector As Outlook.Inspector = Me.Context
inspector.SetCurrentFormPage("MyAddIn.MyFormRegion")

I get an exception on the SetCurrentFormPage() call. Note that this code work perfectly fine when I don't have the "e.Cancel = True" line of code in the form factory initializing method. So I assume I need to somehow instantiate my Form Region when my button is clicked, I'm just not certain how to do it. Any thoughts?

Thanks -- David D

By DavidD on  2/4/2010 6:51 PM

Re: How to programmatically select a custom Form Region

Hi David,

thank you for your comment.
Until now i didn't have a solution or workaround for this problem.
Basically I would try to get the Ribbon, the Group and try find the dynamically generated Button and set visible to false.

If I find some time I will dive into this problem and post it in my Blog.
Greets - Helmut

By Helmut Obertanner on  2/4/2010 6:57 PM

Your name:
Your email:
(Optional) Email used only to show Gravatar.
Your website:
Title:
Comment:
Security Code
Enter the code shown above in the box below
Add Comment  Cancel 
X4U Blog
 
Home  |  Hardware  |  Software  |  Services  |  Resources  |  Impressum