Working with the MAPIFolder Object

This chapter has already covered how to iterate over Folders collections, how to get a MAPIFolder out of a Folders collection using the index operator, how to access Outlook's default folders, how to get a MAPIFolder by EntryID and StoreID, and how to use Outlook's folder picker dialog to get a MAPIFolder. This section now examines some additional properties and methods associated with the MAPIFolder object.

Other Identifiers for a Folder

The MAPIFolder object's Name property returns the display name of a folder as a string. For example, the default server sync failures folder identified by OlDefaultFolders.olFolderServerFailures returns the string "Server Failures" for its Name property.

The MAPIFolder object's FolderPath property returns the full name of the folder as a string, including the names of the containing folders. For example, the default server sync failures folder identified by OlDefaultFolders.olFolderServerFailures returns the string "\Eric CarterSync IssuesServer Failures" for its FolderPath property. For this example, the Server Failures folder is contained in a folder called Sync Issues in the Store called Eric Carter.

The MAPIFolder object's Description property returns a string containing the description of the folder. This is a read/write property that can be set to any string value. The MAPIFolder object's ShowItemCount property controls whether the folder shows the unread item count, total item count, or no count when displayed in the Outlook Navigation pane folder list. It can return or be set to a member of the OlShowItemCount enumeration: olNoItemCount, olShowTotalItemCount, or olShowUnreadItemCount. If you want to determine the number of unread items in a particular folder, use the MAPIFolder object's UnReadItemCount property, which returns an int value representing the unread item count.

Accessing Subfolders Contained in a Folder

A MAPIFolder may contain subfolders. The MAPIFolder object's Folders property returns a Folders collection, which contains any additional MAPIFolder objects that are subfolders of the given folder.

As described earlier, you can iterate over the subfolders contained in the Folders collection for a MAPIFolder using C#'s foreach keyword. You can also get to a particular MAPIFolder in the Folders collection by using the index operator ([]). The index operator can be passed a string representing the name of the Folder in the Folders collection, or a 1-based index representing the index of the Folder within the Folders collection.

The Folders collection's Add method enables you to add a new subfolder to the subfolders associated with a MAPIFolder. The Add method takes the name of the new folder as a string parameter. It also takes as an optional object parameter the Outlook folder type to use for the new folder. You can pass this parameter a subset of the OlDefaultFolders constants: olFolderCalendar, olFolderContacts, olFolderDrafts, olFolderInbox, olFolderJournal, olFolderNotes, olPublicFoldersAllPublicFolders, or olFolderTasks. If you omit this parameter by passing Type.Missing, the Outlook folder type of the newly created folder matches the folder type of the parent folder. Also note that a folder of type olPublicFoldersAllPublicFolders can only be added somewhere under the root public folder returned by the NameSpace object's GetDefaultFolder(olPublicFoldersAllPublicFolders).

The Folders collection's Remove method enables you to remove a subfolder by passing the 1-based index of the folder in the Folders collection. Figuring out what the 1-based index is can be a bit of a painit is usually easier to just call the Delete method on the MAPIFolder object representing the subfolder you want to remove.

Listing 11-13 shows a VSTO add-in that iterates over the subfolders of the Inbox folder, and then adds a new folder using the Folders collection's Add method. It then deletes the newly added folder using the MAPIFolder object's Delete method rather than the Folders collection's Remove method.

Listing 11-13. A VSTO Add-In That Iterates over Subfolders of the Inbox Folder, Adds a New Subfolder, and Then Deletes It

private void ThisApplication_Startup(object sender, EventArgs e) { Outlook.MAPIFolder folder = this.Session.GetDefaultFolder( Outlook.OlDefaultFolders.olFolderInbox); MessageBox.Show(String.Format( "There are {0} subfolders in the Inbox.", folder.Folders.Count)); foreach (Outlook.MAPIFolder subFolder in folder.Folders) { MessageBox.Show(String.Format( "Sub folder {0}.", subFolder.Name)); } Outlook.MAPIFolder newSubFolder = folder.Folders.Add( "New Temporary Folder", missing); MessageBox.Show( "A new subfolder was just added under the Inbox folder"); newSubFolder.Delete(); MessageBox.Show("The new subfolder was just deleted."); }

 

Accessing Items Contained in a Folder

A MAPIFolder's main purpose in life is to contain Outlook items. When you create a new folder, you have to specify the type of folder it is. This type constrains the types of Outlook items it can contain. Figure 11-8 shows Outlook's Create New Folder dialog, which appears when you right-click a folder or root folder (Store) in Outlook and choose New Folder. The Create New Folder dialog makes the user decide what kind of items the folder can contain: Calendar Items, Contact Items, Journal Items, Mail and Post Items, Note Items, or Task Items. This constraint is enforced by Outlookif you try to drag a Mail item to a folder that was created to contain Calendar items, the item type will be changed to a Calendar item.

Figure 11-8. Outlook's Create New Folder dialog.

The MAPIFolder object's Items property returns an Items collection containing Outlook items in the folder. Each Outlook item in the folder is returned as an object. You can use the fact that folders are constrained to contain certain types of Outlook items when iterating over items in a folder. If you check the type of item that folder contains by looking at the DefaultItemType property, you can write code that only tries to cast the objects returned from the Items collection to the Outlook item types that are allowed in that folder. So for example, if you are iterating over items in a Folder whose DefaultItemType property returns olContactItem, objects returned from the Items collection can be cast to either a ContactItem or a DistListItem.

Table 11-7 shows how the member of the OlDefaultFolders enumeration you pass in when you create the folder using Folders.Add corresponds to the returned DefaultItemType and what possible Outlook item types could be found in that folder.

Table 11-7. Relationship Between Folders.Add Folder Type (OlDefaultFolders), DefaultItemType Value, and Outlook Item Types Found in a Folder

Folder Created with OlDefaultFolders Enumeration Member

DefaultItemType Returns OlItemType Enumeration Member

Possible Outlook Item Types in Folder

olFolderCalendar

olAppointmentItem

AppointmentItem

olFolderContacts

olContactItem

ContactItem, DistListItem

olFolderJournal

olJournalItem

JournalItem

olFolderInbox olFolderDrafts

olMailItem

MailItem, PostItem, MeetingItem, RemoteItem, ReportItem, DocumentItem, TaskRequestAcceptItem, TaskRequestDeclineItem, TaskRequestItem, TaskRequestUpdateItem

olFolderNotes

olNoteItem

NoteItem

olPublicFolders-AllPublicFolders

olPostItem

PostItem

olFolderTasks

olTaskItem

TaskItem

Listing 11-14 shows an add-in that iterates over the top-level folders in each open Store and iterates over the items in each of those folders. It uses the DefaultItemType property to determine which kinds of items a particular folder might have in it and casts the objects returned from the Items collection to one of the expected types in the folder. Note that there is a case where the expected cast might fail. An object that is a MailItem that has restricted permissions cannot be cast to a MailItem unless the item has been opened in Outlook in an Inspector window with security permissions verified.

Listing 11-14. A VSTO Add-In That Iterates over Items in Folders and Performs Appropriate Casts

private void ThisApplication_Startup(object sender, EventArgs e) { Outlook.Folders rootFolders = this.Session.Folders; foreach (Outlook.MAPIFolder folder in rootFolders) { Outlook.Folders subFolders = folder.Folders; foreach (Outlook.MAPIFolder subfolder in subFolders) { IterateFolder(subfolder); } } } public void IterateFolder(Outlook.MAPIFolder folder) { System.Text.StringBuilder subject = new System.Text.StringBuilder(); subject.AppendLine(folder.Name); foreach (object item in folder.Items) { subject.AppendLine(GetSubject(item, folder.DefaultItemType)); } MessageBox.Show(subject.ToString()); } public string GetSubject(object item, Outlook.OlItemType type) { switch (type) { case Outlook.OlItemType.olAppointmentItem: Outlook.AppointmentItem appointment = item as Outlook.AppointmentItem; if (appointment != null) return appointment.Subject; break; case Outlook.OlItemType.olContactItem: case Outlook.OlItemType.olDistributionListItem: Outlook.ContactItem contact = item as Outlook.ContactItem; if (contact != null) return contact.Subject; Outlook.DistListItem distlist = item as Outlook.DistListItem; if (distlist != null) return distlist.Subject; break; case Outlook.OlItemType.olJournalItem: Outlook.JournalItem journal = item as Outlook.JournalItem; if (journal != null) return journal.Subject; break; case Outlook.OlItemType.olMailItem: Outlook.MailItem mail = item as Outlook.MailItem; if (mail != null) return mail.Subject; Outlook.PostItem post = item as Outlook.PostItem; if (post != null) return post.Subject; Outlook.MeetingItem meeting = item as Outlook.MeetingItem; if (meeting != null) return meeting.Subject; Outlook.RemoteItem remote = item as Outlook.RemoteItem; if (remote != null) return remote.Subject; Outlook.ReportItem report = item as Outlook.ReportItem; if (report != null) return report.Subject; Outlook.DocumentItem doc = item as Outlook.DocumentItem; if (doc != null) return doc.Subject; Outlook.TaskRequestAcceptItem tra = item as Outlook.TaskRequestAcceptItem; if (tra != null) return tra.Subject; Outlook.TaskRequestDeclineItem trd = item as Outlook.TaskRequestDeclineItem; if (trd != null) return trd.Subject; Outlook.TaskRequestItem tr = item as Outlook.TaskRequestItem; if (tr != null) return tr.Subject; Outlook.TaskRequestUpdateItem tru = item as Outlook.TaskRequestUpdateItem; if (tru != null) return tru.Subject; break; case Outlook.OlItemType.olNoteItem: Outlook.NoteItem note = item as Outlook.NoteItem; if (note != null) return note.Subject; break; case Outlook.OlItemType.olPostItem: Outlook.PostItem post2 = item as Outlook.PostItem; if (post2 != null) return post2.Subject; break; case Outlook.OlItemType.olTaskItem: Outlook.TaskItem task = item as Outlook.TaskItem; if (task != null) return task.Subject; break; } MessageBox.Show(String.Format( "Couldn't cast item with subject {0} and class {1}.", (string)GetPropertyHelper(item, "Subject"), (string)GetPropertyHelper(item, "Class"))); return ""; } 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); }

 

Working with a Folder's View Settings

A MAPIFolder has a Views property that returns a Views collection. The Views collection contains all the available View objects for a folder that correspond to the views shown in the Custom View Organizer dialog in Figure 11-4. You can determine the view currently being used by the folder by accessing the MAPIFolder object's CurrentView property, which returns a View object. The CurrentView property is read-onlyyou cannot change the current view by setting the CurrentView property to another View object. Instead, you must access one of the View objects in the Views collection and call the View object's Apply method to make the view associated with the folder the active view.

Listing 11-15 shows add-in code that gets the name of the current view for the Inbox folder. It then iterates over the available views for the Inbox folder and applies each view.

Listing 11-15. A VSTO Add-In That Iterates over Available Views for the Inbox Folder and Applies Each View

private void ThisApplication_Startup(object sender, EventArgs e) { Outlook.MAPIFolder inbox = this.Session.GetDefaultFolder( Outlook.OlDefaultFolders.olFolderInbox); this.ActiveExplorer().CurrentFolder = inbox; MessageBox.Show(String.Format( "Current inbox view is {0}.", inbox.CurrentView.Name)); foreach (Outlook.View view in inbox.Views) { view.Apply(); MessageBox.Show(String.Format( "Current inbox view is now {0}.", inbox.CurrentView.Name)); } }

 

Copying or Moving a Folder to a New Location

You can copy a folder and its dependent folders and items to a new location using the MAPIFolder object's CopyTo method. The CopyTo method takes a DestinationFolder parameter of type MAPIFolder, which will be the parent folder for the copied folder. It returns a MAPIFolder for the newly copied folder. The copy is a "deep copy" because all the items and subfolders rooted at the folder you call the CopyTo method on are copied to the new location.

You can move a folder and its dependent folders and items to a new location using the MAPIFolder's MoveTo method. The MoveTo method takes a DestinationFolder parameter of type MAPIFolder, which will be the parent folder for the moved folder. The folder is moved along with all dependent folders and items to the new location.

Displaying a Folder in an Explorer View

You can open a MAPIFolder in a new Explorer view by calling the MAPIFolder object's Display method. To use an existing Explorer view, you can set the Explorer object's CurrentFolder to the MAPIFolder you want to display in the existing Explorer view. Listing 11-15 uses this approach.

Категории