Outlook上下文菜单项单击多次

时间:2012-02-14 06:38:47

标签: c# event-handling outlook-addin

这已经被问到here,但我对给出的答案感到不满意。

我目前正在向Outlook添加自定义上下文菜单。代码如下:

void Application_ItemContextMenuDisplay(Microsoft.Office.Core.CommandBar CommandBar, Microsoft.Office.Interop.Outlook.Selection Selection)
    {
        if (Online)
        {
            foreach (string category in FilingRuleManager.FilingRuleCategories)
            {
                Office.CommandBarPopup cb = CommandBar.Controls.Add(Office.MsoControlType.msoControlPopup, missing, missing, missing, true) as Office.CommandBarPopup;
                cb.BeginGroup = true;
                cb.Visible = true;
                cb.Tag = MENUNAME;
                cb.Caption = category;
                //now add the filing rules as a sub menu
                foreach (FilingRuleDB rule in FilingRuleManager.FilingRules.Values)
                {
                    if (rule.RuleCategory == category)
                    {
                        Office.CommandBarButton cbSub = cb.Controls.Add(Office.MsoControlType.msoControlButton, missing, missing, missing, true) as Office.CommandBarButton;
                        _FilingRules.Add(cbSub);
                        cbSub.Visible = true;
                        cbSub.Caption = rule.RuleName;
                        cbSub.Tag = rule.FilingRuleID.ToString();
                        cbSub.Click += new Office._CommandBarButtonEvents_ClickEventHandler(FilingRules_Click);
                    }
                }
            }
        }
    }

当我运行应用程序时,每次我在Outlook中显示上下文菜单时,会多次触发Click处理程序(FilingRules_Click)。因此,如果我右键单击3次,处理程序将执行3次,依此类推。

除了上面提到的问题中的黑客攻击外,必须有更好的方法来实现这一目标。

我试过了:

  1. 在添加CommandBarButtons之前删除它们 - 但它们不存在!!每次隐藏Outlook上下文菜单时,都会自动删除自定义项目。
  2. 将控件存储在List中,然后尝试删除处理程序 - 这会产生AV,因为隐藏菜单后按钮不再存在。
  3. 没有ItemContextMenuHidden()事件让我挂钩,否则我会尝试过。
  4. 在加载项开始时添加项目(即只有一次没有ItemContextMenuDisplay()处理程序),但是项目永远不会出现,因为它们总是在显示菜单时被清除。
  5. 那里有人有另一个建议吗?

1 个答案:

答案 0 :(得分:2)

解决了这个问题。

  1. 将命令按钮定义为类级静态变量
  2. ContextMenuClose的附件事件Outlook.Application

    outlookInstance.ContextMenuClose += new ApplicationEvents_11_ContextMenuCloseEventHandler(outlookInstance_ContextMenuClose);
    
  3. 将该方法实现为代码

    void outlookInstance_ContextMenuClose(OlContextMenu ContextMenu)
    {
        if (ContextMenu == OlContextMenu.olItemContextMenu)
        {
            ContextIndexButton.Click -= new _CommandBarButtonEvents_ClickEventHandler(<your method>);
            ContextIndexButton = null;
        }
    }