我的Outlook上下文菜单(加载项)按钮每点击一次会触发多次 [英] My Outlook context menu (add-in) button fires multiple times per one click

查看:100
本文介绍了我的Outlook上下文菜单(加载项)按钮每点击一次会触发多次的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,除了菜单项的实际选择背后的事件似乎多次触发之外,我已经使此上下文菜单生效了.第一次单击时,它会触发一次,然后触发两次,然后触发3次.因此,在我刚才给出的示例中,单击3次,总共将触发6次(1 + 2 + 3).为什么呢?

下面是我如何创建菜单项的代码.我将其分解为相关的部分;我省略了.Tag,.Visible和.Caption属性之类的内容.我正在使用.NET 3.5和VS 2008进行构建.

提前谢谢!

Private WithEvents ActiveExplorerCBars As Office.CommandBars
Private app As New Outlook.Application

Private Sub ThisAddIn_Startup(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Startup
     ActiveExplorerCBars = app.ActiveExplorer.CommandBars
     AddHandler ActiveExplorerCBars.OnUpdate, AddressOf ActiveExplorerCBars_OnUpdate
End Sub

//This seems to get hit A LOT    
Private Sub ActiveExplorerCBars_OnUpdate()
    Dim bar As Office.CommandBar

    If IgnoreCommandbarsChanges Then Exit Sub

    bar = ActiveExplorerCBars.Item("Context Menu")

    If Not bar Is Nothing Then
        Dim addMenu As Boolean = False
        //this For loop just makes sure the context is only available when the user right-clicks over a mail item
        For Each mail As Outlook.MailItem In Application.ActiveExplorer().Selection
            addMenu = True
            Exit For
        Next
        If addMenu Then
            AddContextDropdown(bar)
        End If
    End If
End Sub

Private Sub AddContextDropdown(ByVal ContextMenu As Office.CommandBar)
    Dim RootPopup As Office.CommandBarPopup
    Dim popupTaskItem As Office.CommandBarPopup
    RootPopup = ContextMenu.FindControl(Type:=Office.MsoControlType.msoControlPopup, Tag:="Update task")

    If RootPopup Is Nothing Then
        ChangingBar(ContextMenu, Restore:=False)
        RootPopup = ContextMenu.Controls.Add(Type:=Office.MsoControlType.msoControlPopup)

        Dim thisTaskPopup As Office.CommandBarPopup
        popupTaskItem = ContextMenu.FindControl(Type:=Office.MsoControlType.msoControlPopup, Tag:=task.EntryID)
        If popupTaskItem Is Nothing Then
              popupTaskItem = RootPopup.Controls.Add(Type:=Office.MsoControlType.msoControlPopup)
              thisTaskPopup = popupTaskItem
              AddActionButtons(thisTaskPopup)
        End If
    End If
End Sub

Private Sub AddActionButtons(ByVal puItem As Office.CommandBarPopup)

    Dim puDeploy As Office.CommandBarPopup = puItem.Controls.Add(Type:=Office.MsoControlType.msoControlPopup)
    Dim btnActionItem As Office.CommandBarControl = puDeploy.Controls.Add(Type:=Office.MsoControlType.msoControlButton)
    Dim thisButton As Office.CommandBarButton = btnActionItem
    AddHandler thisButton.Click, AddressOf OnContextClick
End Sub

//Click event
Public Sub OnContextClick(ByVal ctrl As Microsoft.Office.Core.CommandBarButton, ByRef CancelDefault As Boolean)
   //This messagebox shows once the first time, twice the second, 3 times, etc
    MessageBox.Show("Clicked: " & ctrl.Caption)
End Sub

解决方案

我知道了. tobrien,我用您的最后评论作为得出结论的工具,特别是在您说的地方:

可能是您实际创建的ADDITIONAL(标识相同)回调.

我用来添加处理程序的代码是:

AddHandler thisButton.Click, AddressOf OnContextClick

如何对此签名相同?好吧,只有一个 OnContextClick 子...那么 thisButton 呢?

For Each value As ActivityType.Request In [Enum].GetValues(GetType(ActivityType.Request))
        Dim btnActionItem As Office.CommandBarControl = puRequest.Controls.Add(Type:=Office.MsoControlType.msoControlButton)
        With btnActionItem
            .Tag = puRequest.Tag & "|" & value
            .Caption = [Enum].GetName(GetType(ActivityType.Request), value)
            .Visible = True
        End With
        Dim thisButton As Office.CommandBarButton = btnActionItem
        AddHandler thisButton.Click, AddressOf OnContextClick
    Next

此代码在发生OnUpdate时运行,正如您所知,OnUpdate一直都在发生.因此,从本质上讲,每次OnUpdate命中时,我都会为EXACT SAME BUTTON添加一个附加处理程序,而不是考虑到每次OnUpdate发生时按钮基本上都是新创建的,并且该处理程序存储在内存中.

因此,我需要使按钮控件具有唯一性:

.Tag = puRequest.Tag & "|" & value & "|" & Now.ToBinary().ToString()

我刚刚在.Tag属性的末尾添加了Now.ToBinary().ToString(),以确保每次向用户创建按钮时,它都有一个唯一的标签.现在,事件是唯一的,并且每次单击仅触发一次.

Topien,我要你!尽管我最终回答了我自己的问题,但这并非没有您的指导.谢谢!

So I've got this context menu working out except that the event behind the actual selection of the menu item seems to fire multiple times. First time I click it, it fires once, then twice, then 3 times. So, in the example I just gave, for 3 clicks it would have fired a total of 6 times (1 + 2 + 3). Why is that?

Below is my code on how I'm creating the menu items. I stripped it down to the relevant pieces; I omitted things like .Tag, .Visible, and .Caption properties. I'm building this using .NET 3.5 and VS 2008.

Thanks in advance!!

Private WithEvents ActiveExplorerCBars As Office.CommandBars
Private app As New Outlook.Application

Private Sub ThisAddIn_Startup(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Startup
     ActiveExplorerCBars = app.ActiveExplorer.CommandBars
     AddHandler ActiveExplorerCBars.OnUpdate, AddressOf ActiveExplorerCBars_OnUpdate
End Sub

//This seems to get hit A LOT    
Private Sub ActiveExplorerCBars_OnUpdate()
    Dim bar As Office.CommandBar

    If IgnoreCommandbarsChanges Then Exit Sub

    bar = ActiveExplorerCBars.Item("Context Menu")

    If Not bar Is Nothing Then
        Dim addMenu As Boolean = False
        //this For loop just makes sure the context is only available when the user right-clicks over a mail item
        For Each mail As Outlook.MailItem In Application.ActiveExplorer().Selection
            addMenu = True
            Exit For
        Next
        If addMenu Then
            AddContextDropdown(bar)
        End If
    End If
End Sub

Private Sub AddContextDropdown(ByVal ContextMenu As Office.CommandBar)
    Dim RootPopup As Office.CommandBarPopup
    Dim popupTaskItem As Office.CommandBarPopup
    RootPopup = ContextMenu.FindControl(Type:=Office.MsoControlType.msoControlPopup, Tag:="Update task")

    If RootPopup Is Nothing Then
        ChangingBar(ContextMenu, Restore:=False)
        RootPopup = ContextMenu.Controls.Add(Type:=Office.MsoControlType.msoControlPopup)

        Dim thisTaskPopup As Office.CommandBarPopup
        popupTaskItem = ContextMenu.FindControl(Type:=Office.MsoControlType.msoControlPopup, Tag:=task.EntryID)
        If popupTaskItem Is Nothing Then
              popupTaskItem = RootPopup.Controls.Add(Type:=Office.MsoControlType.msoControlPopup)
              thisTaskPopup = popupTaskItem
              AddActionButtons(thisTaskPopup)
        End If
    End If
End Sub

Private Sub AddActionButtons(ByVal puItem As Office.CommandBarPopup)

    Dim puDeploy As Office.CommandBarPopup = puItem.Controls.Add(Type:=Office.MsoControlType.msoControlPopup)
    Dim btnActionItem As Office.CommandBarControl = puDeploy.Controls.Add(Type:=Office.MsoControlType.msoControlButton)
    Dim thisButton As Office.CommandBarButton = btnActionItem
    AddHandler thisButton.Click, AddressOf OnContextClick
End Sub

//Click event
Public Sub OnContextClick(ByVal ctrl As Microsoft.Office.Core.CommandBarButton, ByRef CancelDefault As Boolean)
   //This messagebox shows once the first time, twice the second, 3 times, etc
    MessageBox.Show("Clicked: " & ctrl.Caption)
End Sub

解决方案

I figured it out. tobrien, I used your last comment as a vehicle to come to this conclusion, particularly where you said:

it could be that your actually creating ADDITIONAL (identically signitured) callbacks

The code I am using to add the handler is:

AddHandler thisButton.Click, AddressOf OnContextClick

How could this be identically signatured? Well, there is only one OnContextClick sub... so what about thisButton?

For Each value As ActivityType.Request In [Enum].GetValues(GetType(ActivityType.Request))
        Dim btnActionItem As Office.CommandBarControl = puRequest.Controls.Add(Type:=Office.MsoControlType.msoControlButton)
        With btnActionItem
            .Tag = puRequest.Tag & "|" & value
            .Caption = [Enum].GetName(GetType(ActivityType.Request), value)
            .Visible = True
        End With
        Dim thisButton As Office.CommandBarButton = btnActionItem
        AddHandler thisButton.Click, AddressOf OnContextClick
    Next

This code runs when OnUpdate occurs, which, as you know, happens ALL the time. So, in essence, each time OnUpdate hits, I'm adding an additional handler for the EXACT SAME BUTTON, not considering that the button is basically created newly each time OnUpdate occurs and that its handler is stored in memory.

So, I needed to make the button control unique:

.Tag = puRequest.Tag & "|" & value & "|" & Now.ToBinary().ToString()

I just added a Now.ToBinary().ToString() at the end of the .Tag property to ensure that each time the button is created to the user, it has a unique tag. Now the events are unique and its only firing once per click.

tobrien, I solute you! Although I ultimately answered my own question, it was not without your guidance. Thanks!

这篇关于我的Outlook上下文菜单(加载项)按钮每点击一次会触发多次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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