Programmatically Adding a Column to Your Outlook 2007 Inbox Table View
In my previous post, I mentioned that I will write an article about adding a new column to your inbox. Here you go!
What we will achieve
Quite simple. Take a look at below screenshot and you will notice that a new column, SubjectLength, is added to the inbox. Its values are the length of individual email’s subject.
How table view is displayed
This backs to the traditional (but useful) discussion of data and view. In view side, we need add a new column to table view via ViewFields.Insert method. In data side, we can easily add a new user property via MailItem.PropertyAccessor. Now the question is how to correlate view with data? The trick here is MAPI property namespace. They both can be referenced this way. OK, now let us talk about details in code.
Step 1: Add new user property to the inbox folder
Before we add new property to the view or items inside a folder, we have to add that property to the folder first. (Assume theFolder is inbox folder we get before hand)
private void AddUserPropertyToFolder(Outlook.Folder theFolder, string userPropertyName) { if (null == theFolder || string.IsNullOrEmpty(userPropertyName)) { return; } // If the user property is not there, create it. Outlook.UserDefinedProperty nameLengthProperty = null; try { nameLengthProperty = theFolder.UserDefinedProperties[userPropertyName]; } catch (Exception ex) { Debug.WriteLine("The UserProperty is not there." + ex.Message + ex.StackTrace); } if (nameLengthProperty == null) { try { theFolder.UserDefinedProperties.Add(userPropertyName, Outlook.OlUserPropertyType.olText, Type.Missing, Type.Missing); } catch (System.Exception exc) { Debug.WriteLine("Error in creating User Property:" + exc.Message + exc.StackTrace); } } } |
Step 2: Add a new field to the inbox table view
Since the inbox folder gets a new user property, we can go ahead to add new field to the inbox table view.
private void AddOneColumnToView(Outlook.Folder theFolder, string userPropertyName) { const int newColumnIndex = 1; if (null == theFolder || string.IsNullOrEmpty(userPropertyName)) { return; } // Update the current view // IMPORTANT: Actually modifying current view is not a encouraged practice // In production code, you'd better clone a new view and change that new one try { Outlook.TableView currentView = theFolder.CurrentView as Outlook.TableView; currentView.ViewFields.Insert(userPropertyName, newColumnIndex); currentView.Save(); currentView.Apply(); } catch (Exception exc) { Debug.WriteLine("Fail to update view: " + exc.Message + exc.StackTrace); } } |
Step 3: Get the prop of newly added column
As we talked about early, MAPI property is the way to connect view and data. So we need get the prop first. If you print the View.XML out, you will find the XML schema is pretty straightforward like below:
<?xml version="1.0" encoding="utf-8"?> <view type="table"> <viewname>Sent To</viewname> <!-- Other elements ommitted --> <column> <heading>SubjectLength</heading> <prop>https://schemas.microsoft.com/mapi/string/{00020329-0000-0000-C000-000000000046}/SubjectLength</prop> <type>string</type> <width>50</width> <style>padding-left:3px;;text-align:left</style> <editable>0</editable> </column> <column> <maxrows>1919942656</maxrows> <heading>Subject</heading> <prop>urn:schemas:httpmail:subject</prop> <type>string</type> <width>226</width> <style>padding-left:3px;;text-align:left</style> <editable>1</editable> </column> <column> <maxrows>1010302976</maxrows> <heading>Sent</heading> <prop>urn:schemas:httpmail:date</prop> <type>datetime</type> <width>110</width> <style>padding-left:3px;;text-align:left</style> <editable>0</editable> <format>M/d/yyyy||h:mm tt</format> <displayformat>2</displayformat> </column> </view> |
If this is case, below LINQ query code can get highlighted prop ID out. (Yeah, you are right that we need .NET3.5 to run the code.)
private string GetColumnProp(Outlook.Folder theFolder, string userPropertyName) { if (null == theFolder || string.IsNullOrEmpty(userPropertyName)) { return null; } // Get LINQ XML elements XElement folderViewXElement = XElement.Parse(theFolder.CurrentView.XML); var props = from Columns in folderViewXElement.Elements("column") where (string)Columns.Element("heading") == userPropertyName select Columns.Element("prop"); // Return the first element which should be the only one foreach (var prop in props) { return prop.Value; } return null; } |
Step 4: Create user property in items with the prop ID
private void AddUserPropertyValuesToItems(Outlook.Folder theFolder, string propName) { if (null == theFolder || string.IsNullOrEmpty(propName)) { return; } // Create user property on all mails Outlook.Items items = theFolder.Items; string columnProp = this.GetColumnProp(theFolder, propName); if (null != columnProp) { foreach (Outlook.MailItem theMail in items) { try { Outlook.PropertyAccessor oPA = theMail.PropertyAccessor; oPA.SetProperty(columnProp, theMail.Subject.Length.ToString()); theMail.Save(); Debug.WriteLine("Mail property is set: " + theMail.Subject); } catch (Exception ex) { Debug.WriteLine("Set mail property goes wrong." + ex.Message + ex.StackTrace); } } } } |
Finally, put above code into the addin entry point which is ThisAddIn_Startup by default, it will do the magic for you.
That is it. Solution file can be found at:
https://www.codeplex.com/bali/SourceControl/changeset/view/10689
Comments
- Anonymous
November 13, 2008
thnx a lot! now I can add a new Persian date column based on received date data.I hope MS add Persian date to the next version of windows ... - Anonymous
December 06, 2008
Hi Bill ,Thanks for a great article .May be you can help with the following :I have a RSS item with custom structure ( different custom XML tags ) and I need to map them to column in RSS reader view in Outlook 2007. Depending on which custom fields I have in RSS Feed , I need to create columns and fill them with values. Do you have a suggestion ? Thanks ! - Anonymous
December 07, 2008
The comment has been removed - Anonymous
February 10, 2009
Hi Bill Li,thanks for ur great article,from where i can get full solution file.pls help me. - Anonymous
February 11, 2009
Hi Kumar, The post has been updated with solution file location. Enjoy! - Anonymous
March 11, 2009
Hi,I am creating outlook add in where i need to group the particular mail id mails together.how can i do that Please provide me some information. - Anonymous
March 11, 2009
Hi Ajay - What do you mean by "mail id"? - Anonymous
July 15, 2009
Great Article and giving a precise insight.I like to know wheather it is possible to replace the outlook view with custom developed winforms. Since one of requirment is to display the outlook folder in diffrent way.Thanks Again. - Anonymous
July 15, 2009
Vytheese - My wild guess is that probably you can.