Properties and Methods Common to Outlook Items
This chapter has discussed the 15 Outlook item types: ContactItem, DistListItem, DocumentItem, JournalItem, MailItem, MeetingItem, NoteItem, PostItem, RemoteItem, ReportItem, TaskItem, TaskRequestAcceptItem, TaskRequestDecline-Item, TaskRequestItem, and TaskRequestUpdateItem. We group these object model types together because all of these types share many common properties and methods listed in Table 11-8. The properties and methods in this table are found on all Outlook item types. The properties and methods marked in this table with an asterisk are found on all Outlook item types except NoteItemNoteItem is a special case in the Outlook item family and has a subset of the properties and methods that the other Outlook item types share.
Actions* | Application | Attachments* |
AutoResolvedWinner | BillingInformation* | Body |
Categories | Class | Close |
Companies* | Conflicts | ConversationIndex* |
ConversationTopic* | Copy | CreationTime |
Delete | Display | DownloadState |
EntryID | FormDescription* | GetInspector |
Importance* | IsConflict | ItemProperties |
LastModificationTime | Links | MarkForDownload |
MessageClass | Mileage* | Move |
NoAging* | InternalVersion* | OutlookVersion* |
Parent | PrintOut | Save |
SaveAs | Saved | Sensitivity* |
Session | ShowCategoriesDialog* | Size |
Subject | UnRead* | UserProperties* |
Creating an Outlook Item
You have already learned the two primary ways in which you can create an Outlook item in the section "Adding an Outlook Item to an Items Collection." You can either call the Items collection's Add method or the Application object's CreateItem method. These methods take a member of the OlItemType enumeration and return an object that can be cast to the Outlook item type corresponding to the OlItemType enumeration, as shown in Table 11-9.
OlItemType member | Outlook Item Type |
---|---|
olAppointmentItem | AppointmentItem |
olContactItem | ContactItem |
olDistributionListItem | DistListItem |
olMailItem | MailItem |
olNoteItem | NoteItem |
olJournalItem | JournalItem |
olPostItem | PostItem |
olTaskItem | TaskItem |
Outlook Item Type | How Created |
---|---|
DocumentItem | The Items collection's Add method also accepts a member of the OlOfficeDocItemsType enumeration: olWordDocumentItem, olExcelWorkSheetItem, or olPowerPointShowItem. Calling the Items collection's Add method with any of these constants returns an object that can be cast to a DocumentItem. You can also create a DocumentItem using the Application object's CopyFile method. |
MeetingItem | Cannot be created directly. Created by Outlook when AppointmentItem.MeetingStatus is set to olMeeting and sent to one or more recipients. |
RemoteItem | Cannot be created directly. Created by Outlook when you use a Remote Access System connection. |
ReportItem | Cannot be created directly. Created by the mail transport system. |
TaskRequestAcceptItem | Cannot be created directly. Created by Outlook as part of the task delegation feature. |
TaskRequestDeclineItem | Cannot be created directly. Created by Outlook as part of the task delegation feature. |
TaskRequestItem | Cannot be created directly. Created by Outlook as part of the task delegation feature. |
TaskRequestUpdateItem | Cannot be created directly. Created by Outlook as part of the task delegation feature. |
Identifying the Specific Type of an Outlook Item
You can determine the specific type of an Outlook item given to you as type object by using the as operator to cast it to the expected type, as shown in Listing 11-21. The code gets an Outlook item out of the Inbox and then uses the as operator to cast it to an Outlook MailItem. If the Outlook item is not a MailItem (for example, it might be a PostItem instead) the mailItem variable will be set to null because the as operator will be unable to cast it to a MailItem. If the casts succeeds, mailItem will be non-null and the code proceeds to display the subject of the mail message.
Listing 11-21. A VSTO Add-In That Uses the as Operator on an Outlook Item of Type object
You can also use the is operator to determine the specific type of an Outlook item. Listing 11-22 shows some code that uses the is operator and then the as operator to cast to either an Outlook.MailItem or an Outlook.PostItem. Using the is and as operators together is considered to be inefficient because this results in two type checks, which is more expensive than just using the as operator and checking whether the result is null, as shown in Listing 11-21.
private void ThisApplication_Startup(object sender, EventArgs e)
{
Outlook.MAPIFolder inbox = this.Session.GetDefaultFolder(
Outlook.OlDefaultFolders.olFolderInbox);
object item = inbox.Items[1];
Outlook.MailItem mailItem = item as Outlook.MailItem;
if (mailItem != null)
MessageBox.Show(mailItem.Subject);
}
Listing 11-22. A VSTO Add-In That Uses the is Operator on an Outlook Item of Type object
A final way to determine the type of an Outlook item of type object is to use reflection to invoke the Class property, which is found on every Outlook item type. The Class property returns a member of the OlObjectClass enumeration. Listing 11-15 would be more efficient if it were rewritten to use the approach in Listing 11-23. The approach in Listing 11-23 only needs to make one reflection call to get the Class value and then one cast using the as operator to get the specific Outlook item type.
private void ThisApplication_Startup(object sender, EventArgs e)
{
Outlook.MAPIFolder inbox = this.Session.GetDefaultFolder(
Outlook.OlDefaultFolders.olFolderInbox);
object item = inbox.Items[1];
if (item is Outlook.MailItem)
{
Outlook.MailItem mailItem = item as Outlook.MailItem;
MessageBox.Show(mailItem.Subject);
}
else if (item is Outlook.PostItem)
{
Outlook.PostItem postItem = item as Outlook.PostItem;
MessageBox.Show(postItem.Subject);
}
}
Listing 11-23. Add-In Code That Uses the Class Property to Determine the Outlook Item Type
private void ThisApplication_Startup(object sender, EventArgs e)
{
Outlook.MAPIFolder inbox = this.Session.GetDefaultFolder(
Outlook.OlDefaultFolders.olFolderInbox);
object item = inbox.Items[1];
Outlook.OlObjectClass objectClass = Outlook.OlObjectClass(
GetPropertyHelper(item, "Class"));
MessageBox.Show(String.Format(
"Class is {0}.",
objectClass.ToString()));
switch (objectClass)
{
case Outlook.OlObjectClass.olAppointment:
break;
case Outlook.OlObjectClass.olContact:
break;
case Outlook.OlObjectClass.olDistributionList:
break;
case Outlook.OlObjectClass.olDocument:
break;
case Outlook.OlObjectClass.olJournal:
break;
case Outlook.OlObjectClass.olMail:
Outlook.MailItem mail = item as Outlook.MailItem;
if (mail != null)
{
MessageBox.Show(String.Format(
"Found mail item with subject {0}.",
mail.Subject));
}
break;
case Outlook.OlObjectClass.olMeetingRequest:
break;
case Outlook.OlObjectClass.olNote:
break;
case Outlook.OlObjectClass.olPost:
Outlook.PostItem post = item as Outlook.PostItem;
if (post != null)
{
MessageBox.Show(String.Format(
"Found post item with subject {0}.",
post.Subject));
}
break;
case Outlook.OlObjectClass.olRemote:
break;
case Outlook.OlObjectClass.olReport:
break;
case Outlook.OlObjectClass.olTask:
break;
case Outlook.OlObjectClass.olTaskRequest:
break;
case Outlook.OlObjectClass.olTaskRequestAccept:
break;
case Outlook.OlObjectClass.olTaskRequestDecline:
break;
case Outlook.OlObjectClass.olTaskRequestUpdate:
break;
default:
}
}
private object GetPropertyHelper(object targetObject,
string propertyName)
{
return targetObject.GetType().InvokeMember(propertyName,
System.Reflection.BindingFlags.Public |
System.Reflection.BindingFlags.Instance |
System.Reflection.BindingFlags.GetProperty,
null,
targetObject,
null,
System.Globalization.CultureInfo.CurrentCulture);
}
Other Properties Associated with All Outlook Items
This section covers several commonly used properties associated with all Outlook item types (with the possible exception of NoteItem). When we say properties in the context of Outlook items, some confusion can arise. Some properties are on the actual Outlook item typefor example, the Subject property is a callable property on all Outlook item object types. There is a MailItem.Subject property, PostItem.Subject, ContactItem.Subject, and so forth. Sometimes a property that is on an Outlook item object type is also accessible via the OutlookItem.ItemProperties collection. If you iterate over the ItemProperties collection, you will find an ItemProperty object where ItemProperty.Name returns "Subject".The creators of the Outlook object model exposed some of the properties in the ItemProperties collection as first-class properties on the object types themselves. So the Subject property can be accessed either by using OutlookItem.Subject or OutlookItem.ItemProperties["Subject"]. Other properties that are more obscure were not exposed out as properties on the objects themselves. For example, the EnableSharedAttachments property can only be accessed via OutlookItem.ItemProperties["EnableSharedAttachments"]. You will learn more about the ItemProperties collection later in this chapter.Table 11-12 lists several properties callable on all Outlook item object types. Properties marked with an asterisk are not available on the NoteItem object.
Name | Type | What It Does |
---|---|---|
Body | string | Gets and sets the body text of the Outlook item. |
Categories | string | Gets and sets the categories assigned to the Outlook item. For example, an Outlook item assigned to the Business and Favorites category would return the string "Business, Favorites". |
ConversationIndex* | string | Gets an identifier for the conversation index. |
ConversationTopic* | string | Gets the conversation topic of the Outlook item. |
Importance* | OlImportance | Gets and sets the importance as a member of the OlImportance enumeration: olImportanceHigh, olImportanceLow, or olImportanceNormal. |
Sensitivity* | OlSensitivity | Gets and sets the sensitivity as a member of the OlSensitivity enumeration: olConfidential, olNormal, olPersonal, or olPrivate. |
CreationTime | DateTime | Gets the DateTime the Outlook item was created. |
LastModificationTime | DateTime | Gets the DateTime the Outlook item was last modified. |
Size | int | Gets the size in bytes of the Outlook item. |
Subject | string | Gets and sets the subject of the Outlook item. |
UnRead* | bool | Gets and sets whether the Outlook item has been open yet by the end user. |
Copying or Moving an Outlook Item to a New Location
An Outlook item can be copied or moved from one folder to another. The Outlook item's Copy method creates a copy of the Outlook item and returns the newly created item as an object. The Outlook item's Move method moves an Outlook item from one folder to another. It takes a DestFldr parameter of type MAPIFolder to which you pass the folder to which you want to move the Outlook item.
Deleting an Outlook Item
To delete an Outlook item, call the Outlook item's Delete method. Doing so causes the Outlook item to be moved to the Deleted Items folder, where it stays until the user empties the Deleted Items folder. If you do not want the item to appear in the Deleted Items folder, you must call Delete twicethe first call moves the item to the Deleted Items folder, and the second call deletes it from the Deleted Items folder, as shown in Listing 11-24.
Listing 11-24. A VSTO Add-In That Deletes an Item, and Then Permanently Deletes It by Removing It from the Deleted Items Folder
Note in Chapter 9, "Programming Outlook." Listing 9-4.
private void ThisApplication_Startup(object sender, EventArgs e)
{
Outlook.MAPIFolder inbox = this.Session.GetDefaultFolder(
Outlook.OlDefaultFolders.olFolderInbox);
Outlook.PostItem postItem = inbox.Items.Add(
Outlook.OlItemType.olPostItem) as Outlook.PostItem;
string subject = "Test Post To Be Deleted";
postItem.Subject = subject;
postItem.Save();
MessageBox.Show("New post item is in inbox");
string entryID1 = postItem.EntryID;
postItem.Delete();
MessageBox.Show("New post item is in deleted items");
Outlook.MAPIFolder deletedItems = this.Session.GetDefaultFolder(
Outlook.OlDefaultFolders.olFolderDeletedItems);
Outlook.PostItem post = deletedItems.Items.Find(
String.Format("[Subject] = '{0}'", subject)) as Outlook.PostItem;
if (post != null)
{
string entryID2 = post.EntryID;
if (entryID1 != entryID2)
{
MessageBox.Show(entryID1);
MessageBox.Show(entryID2);
MessageBox.Show(
"When you delete an item its entry ID changes.");
}
post.Delete();
MessageBox.Show("Removed post from deleted items folder.");
}
}
Listing 11-25. A VSTO Add-In That Uses CDO to Permanently Delete an Outlook Item
public partial class ThisApplication
{
MAPI.Session mapiSession;
private void ThisApplication_Startup(object sender, EventArgs e)
{
mapiSession = new MAPI.Session();
mapiSession.Logon(missing, missing, false, false,
missing, missing, missing);
Outlook.MAPIFolder inbox = this.Session.GetDefaultFolder(
Outlook.OlDefaultFolders.olFolderInbox);
Outlook.PostItem postItem = inbox.Items.Add(
Outlook.OlItemType.olPostItem) as Outlook.PostItem;
postItem.Subject = "Test Post To Be Deleted"; ;
postItem.Save();
MessageBox.Show("New post item is in inbox");
MAPI.Message message = GetMessageFromOutlookItem(postItem);
message.Delete(Type.Missing);
MessageBox.Show("New post item was permanently deleted.");
}
MAPI.Message GetMessageFromOutlookItem(object OutlookItem)
{
object entryID = GetPropertyHelper(OutlookItem, "EntryID");
object parentFolder = GetPropertyHelper(OutlookItem, "Parent");
object storeID = GetPropertyHelper(parentFolder, "StoreID");
return (MAPI.Message)mapiSession.GetMessage(entryID, storeID);
}
private object GetPropertyHelper(object targetObject,
string propertyName)
{
return targetObject.GetType().InvokeMember(propertyName,
System.Reflection.BindingFlags.Public |
System.Reflection.BindingFlags.Instance |
System.Reflection.BindingFlags.GetProperty,
null,
targetObject,
null,
System.Globalization.CultureInfo.CurrentCulture);
}
#region VSTO Designer generated code
private void InternalStartup()
{
this.Startup += new System.EventHandler(ThisApplication_Startup);
}
#endregion
}
Displaying an Outlook Item in an Inspector View
The Outlook item's GetInspector method gives you an Inspector object to display an Outlook item. You can configure the Inspector before showing it by calling the Inspector object's Display method. The Display method takes an optional Modal parameter of type object to which you can pass TRue to show the inspector as a modal dialog or false to show it as a modeless dialog.If you do not need to configure the Inspector first before you display it, you can just use the Display method on an Outlook item. The Display method displays an Inspector and takes an optional Modal parameter of type object to which you can pass TRue to show the inspector as a modal dialog or false to show it as a modeless dialog.If an Inspector window is open for a given Outlook item, you can close the Inspector window by using the Close method on the Outlook item being displayed. The Close method takes a SaveMode parameter of type OlInspectorClose. You can pass a member of the OlInspectorClose enumeration to this parameter: olDiscard to discard changes made in the Inspector window, olPromptForSave to prompt the user to save if changes were made, and olSave to save without prompting.Listing 11-26 creates a PostItem in the Inbox folder then calls the Display method to display an Inspector window for it. It then calls the Close method passing OlInspectorClose.olDiscard to close the Inspector window. Note that we have to cast the PostItem to the Outlook._PostItem interface to disambiguate between the Close method and the Close event, which collide on Outlook item objects.
Listing 11-26. A VSTO Add-In That Uses the Display and Close Method
private void ThisApplication_Startup(object sender, EventArgs e)
{
Outlook.MAPIFolder inbox = this.Session.GetDefaultFolder(
Outlook.OlDefaultFolders.olFolderInbox);
Outlook.PostItem postItem = inbox.Items.Add(
Outlook.OlItemType.olPostItem) as Outlook.PostItem;
postItem.Subject = "Test to be shown in Inspector window.";
postItem.Save();
postItem.Display(false);
MessageBox.Show("Post item is shown in inspector window.");
((Outlook._PostItem)postItem).Close(
Outlook.OlInspectorClose.olDiscard);
}
Working with Built-In and Custom Properties Associated with an Outlook Item
The ItemProperties property returns the ItemProperties collection associated with an Outlook item. This collection contains ItemProperty objects for each property associated with the Outlook item. By property , we mean a name value pair that may or may not also have a get/set property on the Outlook item type. The ItemProperties collection can be iterated over using the foreach keyword. It also supports C#'s index operator ([]). You can pass a string as the index representing the name of the ItemProperty you want to access. You can also pass a 1-based index for the ItemProperty you want to access in the collection.Listing 11-27 shows code that gets an ItemProperty object associated with a newly created PostItem using the index operator with a string and numeric index. Listing 11-27 also illustrates iterating over all the ItemProperty objects in the ItemProperties collection using foreach.
Listing 11-27. A VSTO Add-In That Works with ItemProperty Objects
You can add your own custom properties to an Outlook item. Custom properties that you have added are accessed by using the UserProperties property. An Outlook item's UserProperties property returns a UserProperties collection that contains UserProperty objects representing custom properties you have added to an Outlook item. Just as with the ItemProperties collection, the UserProperties collection can be iterated over using the foreach keyword. A particular UserProperty in the collection can be accessed using the index operator ([]) to which you pass a string representing the name of the UserProperty or the 1-based index of the UserProperty in the collection.To add your own custom property, use the UserProperties collection's Add method. This method takes a required Name parameter of type string to which you pass the name of the new custom property. You must also specify the type of the new property by passing a member of the OlUserPropertyType enumeration. Common members of that enumeration you might use include olDateTime, olNumber, olText, and olYesNo. Other types are also supportedconsult the Outlook object model documentation for more information. The Add method also takes two optional parameters that we omit: AddToFolderFields and DisplayFormat. Note that you can add custom properties to all Outlook item types except the NoteItem and DocumentItem types.Listing 11-28 shows the creation of several custom properties using the UserProperties.Add method.
private void ThisApplication_Startup(object sender, EventArgs e)
{
Outlook.MAPIFolder inbox = this.Session.GetDefaultFolder(
Outlook.OlDefaultFolders.olFolderInbox);
Outlook.PostItem postItem = inbox.Items.Add(
Outlook.OlItemType.olPostItem) as Outlook.PostItem;
MessageBox.Show(String.Format(
"There are {0} properties associated with this post.",
postItem.ItemProperties.Count));
// Getting an ItemProperty with a string index
Outlook.ItemProperty subject = postItem.
ItemProperties["Subject"];
MessageBox.Show(String.Format(
"The property 'Subject' has value {0}.",
subject.Value));
// Getting an ItemProperty with a numeric index
Outlook.ItemProperty firstProp = postItem.
ItemProperties[1];
MessageBox.Show(String.Format(
"The first property has name {0} and value {1}.",
firstProp.Name,
firstProp.Value));
// Iterating the ItemProperties collection with foreach
System.Text.StringBuilder result = new
System.Text.StringBuilder();
foreach (Outlook.ItemProperty property
in postItem.ItemProperties)
{
result.AppendFormat("{0} of type {1} has value {2}.\n",
property.Name, property.Type.ToString(),
property.Value);
}
MessageBox.Show(result.ToString());
}
Listing 11-28. A VSTO Add-In That Works with Custom Properties
private void ThisApplication_Startup(object sender, EventArgs e)
{
Outlook.MAPIFolder inbox = this.Session.GetDefaultFolder(
Outlook.OlDefaultFolders.olFolderInbox);
Outlook.PostItem postItem = inbox.Items.Add(
Outlook.OlItemType.olPostItem) as Outlook.PostItem;
postItem.Subject = "User Properties Test";
postItem.Save();
Outlook.UserProperties userProperties =
postItem.UserProperties;
Outlook.UserProperty dateProp = userProperties.Add(
"DateProp", Outlook.OlUserPropertyType.olDateTime,
missing, missing);
dateProp.Value = System.DateTime.Now;
Outlook.UserProperty numberProp = userProperties.Add(
"NumberProp", Outlook.OlUserPropertyType.olNumber,
missing, missing);
numberProp.Value = 123;
Outlook.UserProperty textProp = userProperties.Add(
"TextProp", Outlook.OlUserPropertyType.olText,
missing, missing);
textProp.Value = "Hello world";
Outlook.UserProperty boolProp = userProperties.Add(
"BoolProp", Outlook.OlUserPropertyType.olYesNo,
missing, missing);
boolProp.Value = true;
MessageBox.Show(String.Format(
"There are now {0} UserProperties.",
userProperties.Count));
postItem.Save();
}
Saving an Outlook Item
As you have already seen, when you create an Outlook item you have to call the Save method or the newly created item gets discarded when your variable containing the newly created item goes out of scope. You can check whether an Outlook item needs to be saved by accessing the Saved property. For example, in Listing 11-28, if we examine the Saved property right before we call postItem.Save at the end of the function, Saved would return false because some changes were made to the Outlook item (user properties were added) after the Save method was earlier in the function. The code in Listing 11-28 actually works even when you omit the last call to Save. Consider what happens, however, if we omit the last call to Save. If you examine the newly created item, its Saved state is still false after this function runs. If you double-click the newly created item to display an Inspector view and then close the Inspector view without making any changes, Outlook prompts users to save the changes made to the item, which is confusing to users because they did not make any changes. Outlook prompts to save because it still detects that it needs to save the changes made to the user properties by the add-in code. If you exit Outlook, Outlook will save the changes to the newly created item and on the next run of Outlook, the saved state of the new item will be back to TRue.
Showing the Categories Dialog for an Outlook Item
You can show the Categories dialog in Figure 11-9 by using the Outlook item's ShowCategoriesDialog method. This dialog allows the user to select categories to associate with an Outlook item. As described earlier, the Outlook item's Categories property enables you to examine what categories an Outlook item is associated with. The Categories property returns a string value with each category associated with the Outlook item in a comma-delimited list.
Figure 11-9. Outlook's Categories dialog.

Mail Properties and Methods
Several commonly used properties and methods are associated with items that would be found in a mail folder, such as a MailItem or a PostItem. The BodyFormat property tells you what format the body of a mail message is in. It sets or gets a member of the OlBodyFormat enumeration: olForm188, olFormatPlain, olFormatRichText, or olFormatUnspecified. When a message is set to have its BodyFormat in olForm188, th192 for the body of the message can be set or get via th192Body property. This property gets and sets the string value, which is th192 content of the message.Figure 11-10 shows the PostItem created by
private void ThisApplication_Startup(object sender, EventArgs e)
{
Outlook.MAPIFolder inbox = this.Session.GetDefaultFolder(
Outlook.OlDefaultFolders.olFolderInbox);
Outlook.PostItem postItem = inbox.Items.Add(
Outlook.OlItemType.olPostItem) as Outlook.PostItem;
postItem.Subject = "HTML Example";
postItem.BodyFormat = Outlook.OlBodyFormat.olForm188;
postIte200Body =
"&l207><BODY><H1>Heading 1</H1><UL><LI>Item 1</LI><LI>Item 2</LI></UL></BODY></HTML>";
postItem.Save();
}
Figure 11-10. PostItem created by Listing 11-29.

Listing 11-30. A VSTO Add-In That Creates a PostItem and Then Forwards It as a MailItem
An identical pattern is followed to reply or reply all to an Outlook item. The original item has its Reply or ReplyAll method called, which generates a new MailItem object. The Recipients collection of the new MailItem object is modified if needed. Finally, the new MailItem object's Send method is invoked to send the new MailItem.
private void ThisApplication_Startup(object sender, EventArgs e)
{
Outlook.MAPIFolder inbox = this.Session.GetDefaultFolder(
Outlook.OlDefaultFolders.olFolderInbox);
Outlook.PostItem postItem = inbox.Items.Add(
Outlook.OlItemType.olPostItem) as Outlook.PostItem;
postItem.Subject = "HTML Example";
postItem.BodyFormat = Outlook.OlBodyFormat.olForm188;
postIte200Body =
"&l207><BODY><H1>Hello World</H1></BODY></HTML>";
postItem.Save();
// Forward the PostItem to someone
Outlook.MailItem forwardedItem =
((Outlook._PostItem)postItem).Forward();
forwardedItem.Recipients.Add("Eric Carter");
((Outlook._MailItem)forwardedItem).Send();
}