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>http://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:


http://www.codeplex.com/bali/SourceControl/changeset/view/10689

Comments (9)

  1. Anonymous says:

    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 …

  2. Anonymous says:

    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 !

  3. MSDN Archive says:

    Hi Leonid,

    Very glad to know you find the article useful. Back to your question, looks like one more thing necessary in your design is the way to specify which field(s) to show in the view at runtime. One of simple ways to do achieve this is command bar button:

    (1) Create command bar for explorer of the interest, add one button inside [CommandBars.Add()]

    (2) In the event handler of button_Click(), show a dialog and populate a list box with fields in your RSS Feed

    (3) In the event handler of OK button in the dialog, process the list user select and you will get to know which field(s) to show at run time

    (4) Show the fields according to this post

    Hope this helps. Have a good day.

  4. Anonymous says:

    Hi Bill Li,

    thanks for ur great article,from where i can get full solution file.pls help me.

  5. Anonymous says:

    Hi Kumar, The post has been updated with solution file location. Enjoy!

  6. Anonymous says:

    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.

  7. MSDN Archive says:

    Hi Ajay – What do you mean by "mail id"?

  8. Anonymous says:

    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.

  9. MSDN Archive says:

    Vytheese – My wild guess is that probably you can.

Skip to main content