user1016945
user1016945

Reputation: 897

Outlook VSTO Add In: AutoFormatRule Filter is not applied

I'm trying to apply auto format rule to Outlook 2016 programmatically. First I've created a rule manually and read the filter property, I've got filter like that:

"(\"urn:schemas:httpmail:read\" = 0 AND \"http://schemas.microsoft.com/mapi/proptag/0x001a001e\" = 'IPM.Note.MyMessage')"

Then I've tried to apply it programmatically:

Dictionary<string, OlColor> colorizationRules = new Dictionary<string, OlColor>()
        {
            {Resources.MsgClass1, OlColor.olColorRed},
            {Resources.MsgClass2, OlColor.olColorYellow},
            {Resources.MsgClass3, OlColor.olColorGreen}
        };

        Explorer explorer = Application.ActiveExplorer();

        if (explorer != null)
        {
            TableView tableView = explorer.CurrentView as TableView;

            if (tableView != null)
            {
                IEnumerable<AutoFormatRule> rules = tableView.AutoFormatRules.Cast<AutoFormatRule>();

                foreach (KeyValuePair<string, OlColor> coloriztionRule in colorizationRules)
                {                       
                    AutoFormatRule newRule = tableView.AutoFormatRules.Add(coloriztionRule.Key);

                    newRule.Filter = $"(\"urn:schemas:httpmail:read\"=0 AND \"http://schemas.microsoft.com/mapi/proptag/0x001a001e\"='{coloriztionRule.Key}')";
                    newRule.Font.Color = coloriztionRule.Value;
                    newRule.Enabled = true;

                    tableView.AutoFormatRules.Save();
                    tableView.Save();
                    tableView.Apply();
                }
            }
        }

Rule is created, but the Filter value is not applied.

One of the suggestions was that Filter value must be prefixed with "@SQL=....". But that does not work.

Then I've found this topic Outlook 2010 AutoFormatRule.Filter property not saving

Where response was:

I raised a premier call in response to this issue. The response was that it is a known bug in the Outlook Object Model. It will not be fixed in Outlook 2010 or Outlook 2013 as the risk is too great for the small change.

And suggested workaround was:

The workaround solution that Microsoft provided was to copy a rule from a Public Folder to the user's profile.

What does that mean? Is there any other workaround to make the rule work from c# code?

Upvotes: 1

Views: 612

Answers (2)

Tony Woodhouse
Tony Woodhouse

Reputation: 163

There is a solution to this problem, albeit a bit messy. It is definitely an Outlook bug that causes programmatically created AutoFormatRules (View Conditional Formatting through the Outlook UI) to be created in a semi-corrupt state which won't persist a change of view or re-load of the application. You can work round the issue by adding an event handler to the Explorer.ViewSwitch event which deletes and re-creates the AutoFormatRule every time the view is changed. This will make it appear as if your conditional formatting rule is working fine.

We've used this technique to implement conditional formatting which highlights emails which are pending tracking to Dynamics CRM by having a conditional formatting rule based on the value of crmLinkState custom attribute on the mail items.

    public partial class BrethertonsAddIn
    {
        Outlook.Explorer _activeExplorer;

        private void ThisAddIn_Startup(object sender, System.EventArgs e)
        {
            _activeExplorer = this.Application.ActiveExplorer();
            _activeExplorer.ViewSwitch += BrethertonsAddIn_ViewSwitch;
            BrethertonsAddIn_ViewSwitch();
        }

        private void BrethertonsAddIn_ViewSwitch()
        {
            Outlook.Explorer olExplorer = Application.ActiveExplorer();
            // Convert the Outlook view into a COM _TableView class which as the AutoFormatRules exposed as properties
            // return if this cast cannot be done
            Outlook._TableView tv = olExplorer.CurrentView as Outlook._TableView;
            if (tv == null) return;
            // Try to find an existing AutoFormatRule for CRM Tracking and delete it
            // Use of the loop is necessary as there is no delete method on the AutoFormatRule object
            // So it's necessary to use the Remove method of a collection object instead
            for (int n = tv.AutoFormatRules.Count; n > 1; n--)
            {
                if (tv.AutoFormatRules[n].Name == "CRM Tracking Pending")
                {
                    tv.AutoFormatRules.Remove(n);
                }
            }
            //Add a new rule and then configure it
            Outlook.AutoFormatRule afr = tv.AutoFormatRules.Add("CRM Tracking Pending");
            afr.Filter = "\"http://schemas.microsoft.com/mapi/string/{00020329-0000-0000-C000-000000000046}/crmLinkState\" = 1";
            afr.Font.Italic = true;
            afr.Font.Bold = true;
            afr.Font.Color = Outlook.OlColor.olColorGreen;
            afr.Enabled = true;
            // Save and apply the changes to the rule
            tv.Save();
            afr.Filter = "\"http://schemas.microsoft.com/mapi/string/{00020329-0000-0000-C000-000000000046}/crmLinkState\" = 1";
            tv.Apply();
            afr.Filter = "\"http://schemas.microsoft.com/mapi/string/{00020329-0000-0000-C000-000000000046}/crmLinkState\" = 1";
        }
}

Upvotes: 5

user1016945
user1016945

Reputation: 897

It's a bug in Outlook and MS does not plan to fix it.

Upvotes: 0

Related Questions