以编程方式将循环菜单添加到Word VSTO加载项中,从而导致出现问题

问题描述

我遵循了这两篇文章中创建VSTO加载项的步骤:

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

我没有使用Ribbon Xml,而是使用了Visual Designer(并通过双击设计器中的事件处理程序属性来添加功能区事件处理程序代码-而是将代码添加到* .designer.cs文件中Ribbon_Load事件,如文章建议)。

也许我必须重新开始并使用Xml,但是我试图将菜单项添加到Word中的各种上下文菜单中,我希望其中的功能区功能可用。

基于this article,我创建了一个List<Office.CommandBarButton> contextMenus = new List<Office.CommandBarButton>();来保存对我创建的每个按钮的引用,以便在初次运行后可以进行后续点击。

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,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 );
    }
}

我有两个问题/问题:

  1. 添加我的按钮后,当我单击其中一个按钮时, insertDocGenContext_Click处理程序会触发14次(每个按钮一次) 我是在循环所需的targetMenus之后创建的,每次 Ctrl.accName是一样的,让我思考如何 现有对按钮的引用,并在其上添加事件处理程序 还有?
  2. 即使我在对以下用户的呼叫中将temporary设置为true cb.Commands.Add(),当我重新启动时它们似乎仍然在那里 Word / Visual Studio,因此需要我的删除循环。

解决方法

CommandBars已过时。您需要使用Fluent UI来自定义Office应用程序中的上下文菜单。在Customizing Context Menus in Office 2010文章中了解有关此内容的更多信息。

,

我解决了我的问题:

对于第一个问题,我在所有项目上都设置了Tag属性,然后使用Word(或VSTO框架)触发具有相同Tag的所有按钮的事件处理程序。 This question and answer通过“ yourTagLabelplusaDiffNumber”注释帮助我指出了正确的方向。

对于第二个问题,我并没有真正解决,但我理解。这篇关于Temporary CommandBarsCustomizationContext in Word addin: No document is open的文章(也有Eugene的评论)对此进行了解释。我没有采用自己的模板来安装一个单独的CustomizationContext的方法,而是只决定在add-的StartupShutdown事件期间删​​除所有添加的菜单。内。

我阅读了Eugene的文章(及相关系列文章),即使使用Xml FluentUI之后,我也不相信我不会遇到同样的问题。我已经使用FluentUI编写了一个Excel加载项,所以我对此很熟悉,并且很幸运,因为在任何按钮上都没有相同的Tag,因此没有遇到问题。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...