首页 > 解决方案 > Outlook.MailItem.PropertyChange 在 9 个事件后停止触发

问题描述

我正在开发一个 Outlook 加载项,该加载项根据我的生产经理发送给我的电子邮件来管理项目列表。我的项目在 Outlook 中的 VBA 中运行良好,但我厌倦了看到使用 VBA 时弹出的安全消息。因此,我将其转换为 .Net 插件。我已经在 c# 中实现了这一点,但是我遇到了 Outlook.MailItem.PropertyChange 事件的事件侦听器的问题。这个想法是我可以使用快速单击类别将电子邮件移动到队列文件夹中,然后在移动后对该电子邮件运行一些处理。

我正在使用下面的代码订阅 Startup 方法中的事件处理程序...

    private void ThisAddIn_Startup(object sender, System.EventArgs e)
    {
        // Get the MAPI namespace
        _olNameSpace = this.Application.GetNamespace("MAPI");

        // Get the Application object
        _olApplication = this.Application;

        // Get the active Explorer object
        _olExplorer = _olApplication.ActiveExplorer();
        if (_olExplorer != null)
        {
            //Inbox Items and event listner(s)
            _olInBxItems = _olApplication.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox).Items;
            foreach (object Item in _olInBxItems)
            {
                if (Item is Outlook.MailItem)
                {
                    _olMailItem = (Outlook.MailItem)Item;
                    _olMailItem.PropertyChange -= new Outlook.ItemEvents_10_PropertyChangeEventHandler(Property_Change);
                    _olMailItem.PropertyChange += new Outlook.ItemEvents_10_PropertyChangeEventHandler(Property_Change);
                }
            }
        }
    }

我遇到的问题是该事件完美触发了大约 9 封电子邮件,然后它停止工作,但资源管理器中的第一封电子邮件除外。对于我的一生,我无法弄清楚其余电子邮件的事件触发器的处理方式。

我在类级别使用以下定义......

    internal static Outlook.NameSpace _olNameSpace { get; set; };
    internal static Outlook.Application _olApplication { get; set; }
    internal static Outlook.Items _olInBxItems { get; set; }
    internal static Outlook.MailItem _olMailItem { get; set; }
    internal static Outlook.Explorer _olExplorer { get; set; }

这是我的 PropertyChange 事件处理程序的定义......

    private static void Property_Change(string Name)
    {
        try
        {
            object curSelect = _olExplorer.Selection[1];
            if (((Outlook.MailItem)curSelect).Categories == "Post WIP")
            {
                MessageBox.Show(string.Format("{0} has changed in the {1} email.", Name, ((Outlook.MailItem)curSelect).Subject));
            }
            ((Outlook.MailItem)curSelect).Save();
        }
        catch(Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }

我错过了什么?提前感谢您的关注。

标签: c#.netoutlook-addinmailitempropertychangelistener

解决方案


我相信我已经解决了我的问题。如果我没记错的话,这是一个超出范围的问题。我现在正在构建一个列表,其中包含资源管理器中订阅事件的电子邮件项目。我现在可以使用 Quick Click 类别超过 9 次,而触发器不会失败。这些是我为使其正常工作所做的更改(***)...

internal static Outlook.NameSpace _olNameSpace { get; set; };
internal static Outlook.Application _olApplication { get; set; }
internal static Outlook.Items _olInBxItems { get; set; }
internal static Outlook.MailItem _olMailItem { get; set; }
internal static Outlook.Explorer _olExplorer { get; set; }

//*** Added this list to keep the emails in scope
internal static List<Outlook.MailItem> _olMIList = new List<Outlook.MailItem>();

private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
    // Get the MAPI namespace
    _olNameSpace = this.Application.GetNamespace("MAPI");

    // Get the Application object
    _olApplication = this.Application;

    // Get the active Explorer object
    _olExplorer = _olApplication.ActiveExplorer();
    if (_olExplorer != null)
    {
        //Inbox Items and event listner(s)
        _olInBxItems = _olApplication.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox).Items;
        foreach (object Item in _olInBxItems)
        {
            if (Item is Outlook.MailItem)
            {
                //*** Changed this bit of code to use the list instead of the static _olMailItem
                ((Outlook.MailItem)Item).PropertyChange -= new Outlook.ItemEvents_10_PropertyChangeEventHandler(Property_Change);
                ((Outlook.MailItem)Item).PropertyChange += new Outlook.ItemEvents_10_PropertyChangeEventHandler(Property_Change);
                _olMIList.Add((Outlook.MailItem)Item);
            }
        }
    }
}

我知道我不需要在订阅之前取消订阅事件处理程序,但如果我这样做不会有任何伤害,并且在处理程序已经订阅的情况下往往会更好地工作。

欢迎任何意见,我仍在学习 c# 和 .net 编程。


推荐阅读