ItemChangeEvent多次触发

时间:2015-04-15 15:30:52

标签: c# outlook add-in

我处理连接到Owncloud(Caldav,Cardav)的Outlook插件。 我使用事件处理程序来检测用户何时删除,创建或更新联系人项目。 在这种情况下,这将通知服务器并在他身边进行更新。

storage.Aitems[storage.Aitems.Count - 1].ItemAdd += new Outlook.ItemsEvents_ItemAddEventHandler(contact_item_add);
storage.Aitems[storage.Aitems.Count - 1].ItemChange += new Outlook.ItemsEvents_ItemChangeEventHandler(contact_item_change);
((MAPIFolderEvents_12_Event)storage.Afolders[storage.Afolders.Count - 1]).BeforeItemMove += new MAPIFolderEvents_12_BeforeItemMoveEventHandler(contact_item_before_move);

当我从服务器找到新的联系人项目时,我将它们添加到地址簿文件夹中。 Outlook会检测新项目或更新,然后触发事件处理程序。这是好的,以防只有一个调用(我可以说这来自服务器不再通知服务器或这是来自用户通知服务器)但我不能,因为事件被多次触发。

static void contact_item_change(object Item) {
        Microsoft.Office.Interop.Outlook.ContactItem contact = (Microsoft.Office.Interop.Outlook.ContactItem)Item;
        System.Diagnostics.Debug.WriteLine("[Modification contact]" + contact.FullName);
        // Need to know if item was created by code (server) or user
        Main.SyncContact(contact);
 }

是否可以通过GUI或我的代码知道项目是否已创建? 我无法设置变量来知道它是由用户还是我的代码创建的,因为多次调用事件。

BTW我已经成功解雇了一次只添加和删除:

static void contact_item_add(object Item) {
        Microsoft.Office.Interop.Outlook.ContactItem contact = (Microsoft.Office.Interop.Outlook.ContactItem)Item;
        if (Contact.GetCreatedByUserProperty(contact, "USER")) {
            if (storage.PreviousAddedContactId != contact.EntryID)
            {
                System.Diagnostics.Debug.WriteLine("[Ajout contact]" + contact.FullName);
                Main.SyncContact(contact);
                storage.PreviousAddedContactId = contact.EntryID;
            }
        }
    }


static void contact_item_before_move(object item, MAPIFolder destinationFolder, ref bool cancel) {
        if ((destinationFolder == null) || (IsDeletedItemsFolder(destinationFolder))) {
            ContactItem contact = (item as ContactItem);
            if (storage.PreviousDeletedContactId != contact.EntryID)
            {
                System.Diagnostics.Debug.WriteLine("[Suppression du contact]" + contact.FullName);
                Main.DeleteContact(contact);
                storage.PreviousDeletedContactId = contact.EntryID;
            }
        }
    }

谢谢!

4 个答案:

答案 0 :(得分:1)

您可以在调用MailItem.Save后立即读取MailItem.LastModificationTime。触发ItemChange事件时,您可以将新的修改时间与缓存的内容进行比较,并检查它是否大于某个增量(1秒?)。

如果是Exchange存储,您还可以检索PR_CHANGE_KEY(DASL名称http://schemas.microsoft.com/mapi/proptag/0x65E20102)属性 - 每次修改后它都会更改。

答案 1 :(得分:0)

  

是否可以通过GUI或我的代码知道项目是否已创建?

不,没有任何属性或方法可以帮助识别用于创建Outlook项目的方式。但是,您可以添加一个用户属性,该属性可能表示该项目是由您的代码以编程方式创建的。用户创建的项目不会设置此属性。

答案 2 :(得分:0)

我按照Dmitry Streblechenko的回答 事实上,ContactItem具有LastModificationTime属性。我不知道我是否错了,但我猜望当他做出改变时,前景永远不会改变这个日期时间。因此,检查用户是否触摸了联系人很容易。这允许我通知服务器,它工作得很好!谢谢 !

static void contact_item_change(object Item) {
        Microsoft.Office.Interop.Outlook.ContactItem contact = (Microsoft.Office.Interop.Outlook.ContactItem)Item;
        // Need to know if item was created by code (server) or user
        var seconds = (DateTime.Now - contact.LastModificationTime).TotalSeconds;
        if (seconds < 2) {
            System.Diagnostics.Debug.WriteLine("[Modification contact]" + contact.FullName);
            Main.SyncContact(contact);
        }
    }

答案 3 :(得分:0)

您只需要关注该项目所需的属性。当ItemChange事件时 触发后,您可以将该项的属性与您的服务器项进行比较,如果它们是差异=&gt; do Main.SyncContact(contact);