Outlook VSTO Explorer.Selection_Change не вызывается - PullRequest
0 голосов
/ 09 мая 2020

В моем плагине VSTO я использую следующие члены класса для хранения указателей на currentExplorer, currentAppointmentItem и currentExplorers.

В Startup я пытаюсь настроить все необходимые обработчики событий следующим образом:

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;

Мои обработчики событий выглядят следующим образом:

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 все еще имеет значение null, поэтому я предполагаю, что он по какой-то причине вызывается во время инициализации Outlook (в это время виден только экран spla sh Outlook)

Что я делаю не так? Я ожидал, что каждый выбор любого элемента (в Mail, Calendar и т.д. c.) Вызовет Selection_Change, но, к сожалению, это не так

Ответы [ 2 ]

0 голосов
/ 10 мая 2020

Юджин был частично прав со своим ответом. Чтобы правильно использовать New_Explorer и Close_Explorer, нужно знать, чтобы поймать событие Close, вам нужно преобразовать ваш Explorer следующим образом:

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

Но истинная причина, по которой это не сработало, заключается в том, что я понимаю: Explorer относится к текущему окну Outlook. Не совсем уверен, что окно Outlook откроется ПОСЛЕ завершения ThisAddIn.Startup. Поэтому приведенная выше кодировка отлично справится с дополнительными windows Outlook, но НЕ с текущим.

Следовательно, вам нужно вручную вызвать New_Explorer из Startup, чтобы инициализировать член currentExplorer (класса, чтобы сохранить ссылку на сохранение from Garbage Colllection) с окном ActiveExplorer (), как это.

New_Explorer(this.Application.ActiveExplorer());

Это инициализирует не только указатель на currentExplorer, но также устанавливает обработчик событий Selection_Change () и Close ().

Теперь все события выбора обрабатываются правильно. Имейте в виду, что Selection_Change, похоже, запускается несколько раз:

К сожалению, при запуске этого решения в отладчике надстройка по-прежнему дает сбой, когда пользователь дважды щелкает серию встреч и выбирает единственную встречу. Никаких исключений не запущено. См. Этот вопрос, который все еще действителен: Outlook VSTO Обработка SelectionChange правильно (в настоящее время при двойном нажатии происходит сбой надстройки)

0 голосов
/ 09 мая 2020

Чтобы события запускались, вы должны постоянно поддерживать исходный объект в рабочем состоянии, поэтому вам нужно объявить ссылку на объект в глобальной области, то есть на уровне класса.

Вы смешали два подхода в коде - Activate / Deactivate обработчики и события NewExplorer / Close. Как я уже писал ранее, вместо обработки событий Activate и Deactivate вы можете обрабатывать событие NewExplorer, где вы можете подписаться на события Close и SelectionChange. В обработчике события Close вы можете отказаться от подписки на событие SelectionChange. Итак, вместо этого вы можете разработать оболочку Explorer. См. Реализация оболочки для инспекторов и отслеживание событий уровня элементов в каждом инспекторе для получения дополнительной информации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...