Share via


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.

Add a column to inbox table

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.