1

所以我已经完成了这个上下文菜单,除了菜单项的实际选择背后的事件似乎触发了多次。我第一次单击它时,它会触发一次,然后是两次,然后是 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
4

1 回答 1

1

我想到了。托布赖恩,我用你最后的评论作为得出这个结论的工具,尤其是在你说的地方:

可能是您实际创建了附加(相同签名)回调

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

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 命中时,我都会为 EXACT SAME BUTTON 添加一个额外的处理程序,而不是考虑到每次 OnUpdate 发生时按钮基本上都是新创建的,并且它的处理程序存储在内存中。

所以,我需要使按钮控件独一无二:

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

我刚刚在 .Tag 属性的末尾添加了一个 Now.ToBinary().ToString() 以确保每次为用户创建按钮时,它都有一个唯一的标签。现在事件是独一无二的,每次点击只会触发一次。

托布赖恩,我解决你!尽管我最终回答了我自己的问题,但并非没有您的指导。谢谢!

于 2010-03-09T15:04:52.453 回答