我的 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
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我想通了。托布莱恩,我用你最后的评论作为得出这个结论的工具,特别是你说的:
我用来添加处理程序的代码是:
这怎么可能是相同签名的?好吧,只有一个 OnContextClick 子项...那么 thisButton 呢?
此代码在 OnUpdate 发生时运行,正如您所知,OnUpdate 一直在发生。因此,本质上,每次 OnUpdate 命中时,我都会为完全相同的按钮添加一个额外的处理程序,而不考虑每次 OnUpdate 发生时该按钮基本上都是新创建的,并且其处理程序存储在内存中。
因此,我需要使按钮控件具有唯一性:
我刚刚在 .Tag 属性末尾添加了 Now.ToBinary().ToString(),以确保每次为用户创建按钮时,它都有一个唯一的标记。现在这些事件是独一无二的,每次点击只会触发一次。
托布莱恩,我向你致敬!虽然我最终回答了我自己的问题,但这并不是没有你的指导。谢谢!
I figured it out. tobrien, I used your last comment as a vehicle to come to this conclusion, particularly where you said:
The code I am using to add the handler is:
How could this be identically signatured? Well, there is only one OnContextClick sub... so what about thisButton?
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:
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!