在一个Outlook 2013的C# VSTO项目中,为什么Explorer SelectionChange事件会触发两次?

5
在我的Outlook 2013 C# VSTO项目中,我发现Explorer SelectionChange事件会触发两次。我曾认为这是由于我的代码存在错误(例如重复挂接事件处理程序),但我未能找到任何此类错误。
因此,我回归基本原理并创建了一个小的VSTO Outlook 2013 Addin测试项目,同样的事情也发生在那里。Explorer SelectionChange事件被触发两次。
public partial class ThisAddIn
{
    private Explorer _activeExplorer;

    private void ThisAddIn_Startup(object sender, System.EventArgs e)
    {
        _activeExplorer = Application.Explorers[1];

        _activeExplorer.SelectionChange += _activeExplorer_SelectionChange;
    }

    private void _activeExplorer_SelectionChange()
    {
        System.Diagnostics.Debug.WriteLine("_activeExplorer_SelectionChange : " + DateTime.Now.ToString());
    }

    private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
    {
    }

    #region VSTO generated code

    /// <summary>
    /// Required method for Designer support - do not modify
    /// the contents of this method with the code editor.
    /// </summary>
    private void InternalStartup()
    {
        this.Startup += new System.EventHandler(ThisAddIn_Startup);
        this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
    }

    #endregion
}

我可以绕过这个问题,但是SelectionChange事件不应该触发两次。

有什么想法为什么SelectionChange事件会被触发两次吗? 除了编写自己的代码检查选择是否已更改之外,我还能做些什么以使其仅触发一次?


你是如何确定它会触发两次的?你是否确保在调试会话之间关闭了Outlook?你没有在Shutdown期间取消订阅,因此在调试期间可能会向同一资源管理器实例订阅两次。 - Panagiotis Kanavos
1
我认为你不会直接得到这个问题的答案。它确实会触发两次(正如每个使用此事件的人都可以证实的那样),但我怀疑你不会得到官方解释为什么会这样。那个“检查选择是否已更改”的解决方法是我见过的每个耗时的SelectionChange事件处理程序的一部分。 - Paul-Jan
你打开了多少个资源管理器窗口?尝试使用ActiveExplorer方法而不是索引器。这有帮助吗?最后,你是否安装了其他Outlook插件? - Eugene Astafiev
2个回答

4

您需要在Outlook中关闭阅读窗格:

enter image description here

关闭后,您将一次只能查看一个事件。


关闭了阅读窗格,只触发了1个SelectionChange事件。谜团解开了。谢谢。 - m_collard
9
抱歉,但这不是解决问题的真正方法。您无法强制用户关闭阅读窗格 - 这对于Outlook用户来说是一种绝对的舒适功能。 :| 翻译:抱歉,但这不是问题的真正解决方案。您无法强制用户关闭阅读窗格 - 这是 Outlook 用户的一个绝对舒适功能。 :| - Mario Fraiß

0
private void ThisAddIn_Startup(object sender, EventArgs e){
    Application.ActiveExplorer().SelectionChange += activeExplorer_SelectionChange;
}
private void activeExplorer_SelectionChange()
{
    Selection selection = Application.ActiveExplorer().Selection;
    if (selection != null && selection.Count == 1 && selection[1] is MailItem)
    {
        MailItem selectedMail = selection[1] as MailItem;
        selectedMail.Read += SelectedMail_Read;
    }
}

private void SelectedMail_Read()
{
     Selection selection = Application.ActiveExplorer().Selection;
     MailItem selectedMail = selection[1] as MailItem;
     ...
}

4
虽然这份代码或许可以回答问题,但是提供关于为什么和/或如何回答问题的额外上下文信息,能够提升其长期价值。 - Tân

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接