我有一个Outlook加载项,每当更改任务/约会项目时我都需要进行一些计算。
我设法通过Inspector Wrapper获取了Item.Write和Item.BeforeDelete事件。这些工作非常好,但这还不够,因为Outlook中有更多事件可以改变(或做其他事情)对象。
Appointment MOVE事件中最重要的事件之一,我在日历中拖放日历项目,并更改其日期。 经过进一步检查后,我发现,BeforeItemMoveEventHandler对此并不是很好,所以我只是简单地使用Item集合对象上的ItemChange事件。 为了实现这一点,我有一个在启动时运行的函数,看起来像这样:
public Outlook.ItemsEvents_ItemChangeEventHandler ChangeHandler;
public Outlook.MAPIFolderEvents_12_BeforeItemMoveEventHandler MoveHandler;
public void SetupEventHandlers()
{
Outlook.Application app = Globals.ThisAddIn.Application;
Outlook.NameSpace ns = app.GetNamespace("mapi");
Outlook.MAPIFolder calendar = null;
Outlook.Folder calendarFolder = null;
Outlook.Items appointments = null;
try
{
calendar = OutlookHelper.GetMAPIFolderByName("My Calendar");
appointments = calendar.Items;
ChangeHandler = new Outlook.ItemsEvents_ItemChangeEventHandler(Appointments_ItemChange);
appointments.ItemChange += ChangeHandler;
calendarFolder = OutlookHelper.GetOutlookFolderByName("My Calendar");
MoveHandler = new Outlook.MAPIFolderEvents_12_BeforeItemMoveEventHandler(Appointments_ItemMove);
calendarFolder.BeforeItemMove += MoveHandler;
}
catch (Exception ex)
{
//failed to get calendar, and to add the itemchange event;
}
}
我在许多地方都读过,必须将事件指定为全局变量,以便不进行垃圾回收。
尝试了两种方式,但结果是,事件被触发2-5次然后它就会停止,没有任何错误消息。
那里的2个子功能(GetMAPIFolderByName和GetOutlookFolderByName)100%返回请求的对象和类型。如果它们是问题的根源,那么根本不起作用。
问题#1 启动应用程序时会触发Appointments_ItemChange事件。因为我希望服务器同步类型的事情与这些事件相关联,所以在启动时使用不必要的数据对服务器进行调用并不是很好。应该有一种方法可以在启动时忽略这个ItemChange事件......?
问题#2 这些事件是随机发射的!我安装了一个Outlook事件监视器加载项,它显示了触发了什么类型的事件以及何时调用它们,有时它甚至会在1分钟后触发ItemChange事件。此外,它会触发多个(为了解决这个问题,我有一个种解决方案,你可以在下面的代码示例中看到)
Appointments_ItemChange函数看起来像这个
public Boolean AppointmentThreadRunning = false;
public Thread AppointmentItemChangeThread;
public void Appointments_ItemChange(object Item)
{
if (!AppointmentThreadRunning) //check if there is a running thread
{
AppointmentItemChangeThread = new Thread(delegate ()
{
AppointmentItemChangeThreadedFunction(Item); //call the thread which will change the value of the boolean and keep it for 3 seconds
});
AppointmentItemChangeThread.Start();
Outlook.AppointmentItem appt = (Outlook.AppointmentItem)Item;
CallSyncAppointmentChange(appt); //call the sync server function
}
}
public void AppointmentItemChangeThreadedFunction(dynamic OutlookItem)
{
AppointmentThreadRunning = true;
//wait 3 seconds, so if Outlook decides to fire another ItemChange it will not call the SYNC
Thread.Sleep(3000);
AppointmentThreadRunning = false;
}
答案 0 :(得分:0)
仅使事件处理程序成为类变量是不够的。我不得不将约会(Outlook.Items类型)作为一个全局变量......