0
votes

I followed the steps of creating a VSTO addin from these two articles:

  1. Create your first VSTO Add-in for Word
  2. Create a custom tab by using the Ribbon Designer

I didn't use Ribbon Xml, rather, I used the Visual Designer (and added ribbon event handler code simply by double clicking the event handler property in the designer - which added the code to the *.designer.cs file instead of Ribbon_Load event like article suggested).

Maybe I have to start over and use Xml instead, but I'm trying to add a menu item to various context menus in Word where I want one of my ribbon functions available.

Based on this article, I created a List<Office.CommandBarButton> contextMenus = new List<Office.CommandBarButton>(); to hold a reference to each button I create so that subsequent clicks worked after the initial run.

private void insertDocGenContext_Click( Office.CommandBarButton Ctrl, ref bool CancelDefault )
{
    System.Diagnostics.Trace.WriteLine( "Click triggered on " + Ctrl.accName );
    var ribbon = Globals.Ribbons.GetRibbon<Ribbon>();
    ribbon.configInsert_Click( null, null );
}

private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
    var targetMenus = new[] { "Form Fields", "Text", "Headings", "Fields", "Lists", "Table Lists", "Table Cells", "Table Text", "Table Headings" };
    var commandBars =
        Application.CommandBars.OfType<Office.CommandBar>()
            .Where( cb => cb.Position == Office.MsoBarPosition.msoBarPopup && targetMenus.Contains( cb.Name ) )
            .ToArray();

    foreach ( var cb in commandBars )
    {
        // I've set 'true' for temporary when I add, but they still seem to be there when I restart word
        var commandsToRemove =
            cb.Controls.OfType<Office.CommandBarButton>().Where( c => c.Tag == "RBLe.InsertDocGen" ).ToArray();

        foreach ( var r in commandsToRemove )
        {
            r.Delete( false );
            System.Diagnostics.Trace.WriteLine( "Deleted RBLe.InsertDocGen from " + cb.Name );
        }

        var button = (Office.CommandBarButton)cb.Controls.Add( Office.MsoControlType.msoControlButton, missing, missing, missing, true );

        button.BeginGroup = true;
        button.Caption = "Insert/Edit DocGen Field";
        button.Tag = "RBLe.InsertDocGen";
        button.accName = button.Tag + "." + cb.Name;

        button.Click += insertDocGenContext_Click;

        contextMenus.Add( button );

        System.Diagnostics.Trace.WriteLine( "Added RBLe.InsertDocGen to " + cb.Name );
    }
}

I have two problems/questions:

  1. After adding my buttons, when I click on one of them, the insertDocGenContext_Click handler fires 14x (once for each button I've created after looping my desired targetMenus), and every time the Ctrl.accName is the same, making me think somehow I'm getting an existing reference to a button and adding the event handler over and over?
  2. Even though I set temporary to true in my call to cb.Commands.Add(), they still appear to be there when I restart Word/Visual Studio, thus needing my delete loop.
2

2 Answers

0
votes

CommandBars were deprecated. You need to use the Fluent UI to customize context menus in Office applications. Read more about that in the Customizing Context Menus in Office 2010 article.

0
votes

I solved my issues:

For the first issue, I was setting the Tag property the same on all items, and either Word (or the VSTO framework) was then triggering the event handler for all buttons with the same Tag. This question and answer helped point me in the correct direction with the 'yourTagLabelplusaDiffNumber' comment.

For the second issue, I didn't really solve it, but I understand it. This article on Temporary CommandBars and CustomizationContext in Word addin: No document is open (which has a comment from Eugene as well) explained it. I didn't go the route of installing my own template to have a separate CustomizationContext, but instead just settled on removing all my added menus during the Startup and Shutdown events of my add-in.

I read the article (and associated series) from Eugene, and I'm not convinced I wouldn't have had the same issues even after using the Xml FluentUI. I've written an Excel Add-in using the FluentUI so I am familiar with it and probably just got lucky by not having the same Tag on any of the buttons therefore not experiencing the problem.