Outlook VSTO Explorer.Selection_Change 不会被调用 [英] Outlook VSTO Explorer.Selection_Change doesn not get called

查看:89
本文介绍了Outlook VSTO Explorer.Selection_Change 不会被调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的 VSTO 插件中,我使用以下类成员来存储指向 currentExplorer、currentAppointmentItem 和 currentExplorers 的指针.

In my VSTO plugin I use the following class members to store pointers to currentExplorer, currentAppointmentItem and currentExplorers.

在启动时,我尝试设置所有必要的事件处理程序,如下所示:

In Startup I try to setup all necessary event handlers like this:

currentExplorers = this.Application.Explorers;

foreach (Outlook.Explorer explorer in currentExplorers)
{
    ((Outlook.ExplorerEvents_10_Event)explorer).Activate +=
    new Outlook.ExplorerEvents_10_ActivateEventHandler(
    Explorer_Activate);

    explorer.Deactivate += new
    Outlook.ExplorerEvents_10_DeactivateEventHandler(
    Explorer_Deactivate);
}

currentExplorers.NewExplorer += New_Explorer;

我的事件处理程序如下所示:

My event handlers look like this:

void New_Explorer(Outlook.Explorer explorer)
        {
            if (currentExplorer != null)
            {
                Marshal.ReleaseComObject(currentExplorer);
            }
            currentExplorer = explorer;
            currentExplorer.SelectionChange += new Outlook.ExplorerEvents_10_SelectionChangeEventHandler(Selection_Change);
            currentExplorer.Deactivate += new Outlook.ExplorerEvents_10_DeactivateEventHandler(Explorer_Deactivate);

        }

        void Explorer_Deactivate()
        {
            if (currentExplorer != null)
            {
                currentExplorer.SelectionChange -= new Outlook.ExplorerEvents_10_SelectionChangeEventHandler(Selection_Change); ;
                Marshal.ReleaseComObject(currentExplorer);
                currentExplorer = null;
            }

        }

        void Explorer_Activate()
        {
            if (currentExplorer != null)
            {
                Marshal.ReleaseComObject(currentExplorer);
            }
            currentExplorer = this.Application.ActiveExplorer();
            currentExplorer.SelectionChange += new Outlook.ExplorerEvents_10_SelectionChangeEventHandler(Selection_Change);
        }


        private void Selection_Change()
        {
            if (currentExplorer == null)
            {
                return;
            }

            try
            {
                Outlook.MAPIFolder selectedFolder = currentExplorer.CurrentFolder;
                if (currentExplorer.Selection.Count > 0)
                {
                    Object selObject = currentExplorer.Selection[1];
                    if (selObject is Outlook.AppointmentItem)
                    {
                        if (currentAppointmentItem != null)
                        {
                            Marshal.ReleaseComObject(currentAppointmentItem);
                        }
                        currentAppointmentItem = (Outlook.AppointmentItem)selObject;
                    }
                    else
                    {
                        currentAppointmentItem = null;
                    }
                }
            } catch(Exception ex)
            {
                log.Error(ex.Message);
            }
        }

我在每个事件处理程序上设置断点问题是当我调试 Outlook 插件时,除了 Explorer_Deactivate 之外,没有任何事件处理程序被调用.当我在那里调试时,我看到 currentExplorer 仍然为空,所以我认为它在 Outlook 初始化期间由于某种原因被调用(当时只有 Outlook 的启动画面可见)

I setup break points on every event handler Problem is when I debug my Outlook plugin none of the event handlers gets called except for Explorer_Deactivate. When I debug in there I see the currentExplorer is still null, so I assume it gets called for some reason during initialization of outlook (at that time only the splash screen of Outlook is visible)

我做错了什么?我原以为任何项目的每一个选择(在邮件、日历等中)都会调用 Selection_Change 但不幸的是,情况并非如此

What I am doing wrong? I would have expected that each and every selection of any item (in Mail, Calendar etc.) will call Selection_Change but this is unfortunately not the case

推荐答案

Eugene 的回答部分正确.要正确使用 New_Explorer 和 Close_Explorer,您需要知道捕捉关闭事件您需要像这样投射您的资源管理器:

Eugene was partly right with his answer. To correctly use New_Explorer and Close_Explorer one needs to know to catch the Close Event you need to cast your Explorer like this:

    ((Outlook.ExplorerEvents_10_Event)currentExplorer).Close += new Outlook.ExplorerEvents_10_CloseEventHandler(Explorer_Close);

但是这不起作用的真正原因是我的理解:资源管理器指的是当前的 Outlook 窗口.并不完全确定在 ThisAddIn.Startup 完成后 Outlook 窗口是否打开.因此,上面的编码将完美地处理 Outlook 的附加窗口,而不是当前的窗口.

But the true reason why this didn't work is from what I understand: the Explorer refers to to the current Outlook Window. It is not completely sure that the Outlook window opens AFTER the ThisAddIn.Startup is done. Therefore the coding above will handle perfectly additional windows of Outlook but NOT the current one.

因此,您需要从 Startup 中手动调用 New_Explorer 以使用 ActiveExplorer() 窗口初始化 currentExplorer 成员(该类的类以保持从垃圾收集中保存的引用).

Therefore you need to manually call New_Explorer from within the Startup to initialize the currentExplorer member (of the class to keep the reference save from Garbage Colllection) with the ActiveExplorer() window like this.

New_Explorer(this.Application.ActiveExplorer());

这不仅会初始化指向 currentExplorer 的指针,还会设置 Selection_Change() 和 Close() 事件处理程序.

This initializes not only the pointer to the currentExplorer but also sets up the Selection_Change() and the Close() event handler.

现在所有选择事件都得到正确处理.请记住,Selection_Change 似乎被多次触发:

Now all selections events are handled correctly. Do keep in mind that Selection_Change seems to be fired multiple times:

不幸的是,在调试器中运行此解决方案时,当用户双击约会系列并选择单个约会时,插件仍然崩溃.没有例外被解雇.请参阅仍然有效的此问题:Outlook VSTO 正确处理选择更改(当前双击崩溃插件)

Unfortunately running this solution in Debugger the Addin still crashes when user double clicks on an appointment series and selects the single appointment. No exceptions fired. See this issue which is still valid: Outlook VSTO Handling SelectionChange correctly (currently doubleclick crashes Addin)

这篇关于Outlook VSTO Explorer.Selection_Change 不会被调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆