C# 使用VSTO在Outlook 2010中创建命令按钮

C# 使用VSTO在Outlook 2010中创建命令按钮,c#,outlook,vsto,C#,Outlook,Vsto,我正在看一些创建Outlook上下文菜单按钮的示例,如下所示: private void Application_ItemContextMenuDisplay(Microsoft.Office.Core.CommandBar CommandBar, Selection Selection) { var button = (Office.CommandBarB

我正在看一些创建Outlook上下文菜单按钮的示例,如下所示:

    private void Application_ItemContextMenuDisplay(Microsoft.Office.Core.CommandBar CommandBar, 
                                                    Selection Selection)
    {

        var button = (Office.CommandBarButton)CommandBar.Controls.
                            Add(Office.MsoControlType.msoControlButton, missing,
                                missing, missing, missing);            
        button.accName = "SowSelectedItem";
        button.DescriptionText = "Show Selected item";
        button.Caption = button.DescriptionText;
        button.Tag = "ShowSelectedItem";
        button.Click += ContextMenuItemClicked;
    }
一旦正确,它就可以在菜单上创建一个按钮,并且可以单击,并且我的事件处理程序在第一次访问时启动

但是,菜单激活会反复触发,每次运行时,似乎都会添加另一个事件处理程序(但菜单上只显示一个按钮),因此,现在单击按钮会多次触发处理程序(以前每次访问一次),而单击处理程序会不断累积(即使每次我都添加一个新按钮)

好的,我想我可以:

  • 设置标志并仅加载按钮一次(在后续激活时不显示)
  • 缓存按钮并每次添加(后续激活时也不会显示)
  • 缓存并使按钮每次可见并启用(不显示)

我觉得我错过了一些东西。如何连接按钮,以便获得正确的按钮激活,并且只命中一个事件处理程序?

我仍然不太确定Outlook对按钮做了什么,但下面的代码通过实现菜单激活和取消激活以及在取消激活中删除事件处理程序来解决问题

public partial class ContextMenuLookupAddin
{
    Outlook.Explorer currentExplorer = null;
    CommandBarButton contextButton = null;

    private void ThisAddIn_Startup(object sender, System.EventArgs e)
    {
        currentExplorer = Application.ActiveExplorer();
        Application.ItemContextMenuDisplay += Application_ItemContextMenuDisplay;
        Application.ContextMenuClose +=Application_ContextMenuClose;
    }

    private void Application_ItemContextMenuDisplay(Microsoft.Office.Core.CommandBar CommandBar, 
                                                    Selection Selection)
    {
        if (contextButton == null)
        {
            contextButton = (Office.CommandBarButton)CommandBar.Controls.
                                Add(Office.MsoControlType.msoControlButton, missing,
                                    missing, missing, missing);

            contextButton.accName = "SowSelectedItem";
        }

        contextButton.DescriptionText = "Show Selected item";
        contextButton.Caption = contextButton.DescriptionText;
        contextButton.Tag = "ShowSelectedItem";
        contextButton.FaceId = 4000;
        contextButton.OnAction = "OutlookIntegration.ThisAddIn.ContextMenuItemClicked";
        contextButton.Click += ContextMenuItemClicked;
    }

    private void Application_ContextMenuClose(OlContextMenu ContextMenu)
    {
        contextButton.Click -= ContextMenuItemClicked;
        contextButton.Delete(missing);
        contextButton = null;
    }

    private void ContextMenuItemClicked(CommandBarButton Ctrl, ref bool CancelDefault)
    {
        if (currentExplorer.Selection.Count > 0)
        {
            object selObject = currentExplorer.Selection[1];
            if (selObject is MailItem)
            {
                // do your stuff with the selected message here
                MailItem mail = selObject as MailItem;
                MessageBox.Show("Message Subject: " + mail.Subject);
            }
        } 
    }
 }