问题描述
我正在开发一个 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);
}
}
我错过了什么? 提前感谢您的观看。
解决方法
设置事件处理程序时,在添加之前删除它是不必要的:
_olMailItem.PropertyChange -= new Outlook.ItemEvents_10_PropertyChangeEventHandler(Property_Change);
_olMailItem.PropertyChange += new Outlook.ItemEvents_10_PropertyChangeEventHandler(Property_Change);
您应该可以像这样为每个邮件项目添加:
_olMailItem.PropertyChange += new Outlook.ItemEvents_10_PropertyChangeEventHandler(Property_Change);
,
我相信我已经解决了我的问题。如果我没记错的话,那是超出范围的问题。我现在正在构建一个列表,其中包含资源管理器中订阅事件的电子邮件项目。我现在可以使用 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 编程。
,为收件箱文件夹中的每个项目设置一个事件处理程序是一个可怕的想法。不要那样做。它会在最糟糕的时刻彻底失败。如果文件夹中的项目超过几百个,它肯定会在在线模式下失败。
捕获 Explorer.SelectionChange
事件并仅在选定的项目(来自 Explorer.Selection
集合)上设置事件处理程序是可以的,只要您立即使用 { 释放对旧项目的引用{1}}。