My
previous post started to explore the possibility to add form regions to the built-in Outlook forms and this post will continue where I left off.
Handling the State of the Form Region
For the fields in the form region to do anything useful we need to hook up some code with the form region and its controls. For this purpose I have created a base class called BaseFormRegionWrapper. The class has three purposes; it has a couple of protected fields for referencing the FormRegion, the UserForm and the Item. It implements IDisposable to make a safe release of this COM objects by calling Marshal.ReleaseComObject and finally it exposes a Close event.
I inherit from this abstract base class in my implementing CalendarFormRegionWrapper that is supposed to handle this specific form region. The constructor sets up the fields in the base class and also hooks up a reference to the controls in the form region.
public CalendarFormRegionWrapper(MSOutlook.FormRegion region)
{
//Set base class properties
this.Item = region.Item;
this.appointment = (MSOutlook.AppointmentItem)this.Item;
this.FormRegion = region;
this.UserForm = FormRegion.Form as Forms.UserForm;
//Hook up events
FormRegion.Close += new Microsoft.Office.Interop.Outlook.FormRegionEvents_CloseEventHandler(FormRegion_Close);
this.appointment.Write += new Microsoft.Office.Interop.Outlook.ItemEvents_10_WriteEventHandler(AppointmentItem_Write);
//Initialize controls
InitalizeControls();
FillProjectsCombo();
LoadWorkItem();
HookEvents();
}
When the base class fields are set up I also makes sure to catch the Close event of the Form Region from which I raises the Close event of the base class. The Write event of the appointment item is called when the Appointment form is saved and I use that event to store my extra collected information (see below). In InitalizeControls I make sure to get a reference to each of the controls from my form region.
this.projectsComboBox = UserForm.Controls.Item("projectsComboBox") as MSOutlook.OlkComboBox;
Now all you have to do is to implement the logic needed for your form region to come alive. One thing that you most likely would want to do is to store the collected information somewhere.
Store Extra Information as Hidden Attachments
A great place to store the information that the user has entered in your form region is by adding an attachment to the appointment item. You can do this by calling the Add method of the Attachments collection.
attachments.Add(tempFileName, Type.Missing, 0, Type.Missing);
By using 0 as the position argument the attachment will be hidden for the user. It is files that can be added as attachments, so before calling Add I have serialized my object representing the information with the XmlSerializer to a temporary file which I also deletes after calling Add.
To load the form region with previously stored data I of course just do the reverse: saves the attachment to a file, deserializes it and removes the file.
Hooking the Last Parts Together
In my last post I never implemented the BeforeFormRegionShow method of the FormRegionStartup interface. This is the last part that needs to be done before your form region can rock the world!
public void BeforeFormRegionShow(MSOutlook.FormRegion formRegion)
{
BaseFormRegionWrapper wrapper = null;
// Determine which form region wrapper class to use based on the region name
switch (formRegion.InternalName)
{
case "WorkItemAdjRegion":
wrapper = new IRM.Office.Outlook.CalendarFormRegionWrapper(formRegion);
break;
}
// Add the region to our list of known regions
if (wrapper != null)
{
knownRegions.Add(wrapper);
// Handle the close event of the wrapper so we can clean up our resources
wrapper.Close += newEventHandler(FormRegion_Close);
}
}
Summary
If you have read this far I guess you are really interested in creating your own form regions. Ryan's
blog and his article are great resources that you should start with and my implementation is heavily based on them.
Sorry for two long posts, but it wasn't easy to keep them even at this length.