【问题标题】:How do I connect to an office fluent ribbon at runtime and add/manipulate a ribbon tab in c#?如何在运行时连接到 Office fluent 功能区并在 C# 中添加/操作功能区选项卡?
【发布时间】:2019-07-31 01:20:40
【问题描述】:

我想连接到正在运行的 excel,或启动 excel,并在运行时在根/主功能区/菜单栏上添加一个选项卡。当我通过互操作连接到 excel 应用程序对象时,我看到了一个动态对象菜单栏。它在运行时解析为我无法解析的 .com 对象。

我可以遍历每个菜单并查看 menu.name、ID 和菜单项。它看起来像我正在运行的 excel 中的功能区项目,但我无法在运行时添加、删除或影响项目。 menus、menu、menuitem 都是微软私有的。我缺少什么来解决和添加/操作/删除我自己的运行时菜单项?我不想编写和编译静态或运行时 xml(还)。我看到其他供应商这样做。我缺少什么程序集或包括什么?这是我从纯粹的黑客攻击中得到的。

using System;
using System . Collections . Generic;
using System . Linq;
using System . Text;
using System . Threading . Tasks;
using Microsoft.Office.Core;
using System . Linq . Expressions;
using Microsoft . Office . Interop . Outlook;
using Microsoft . Office . Interop . Excel;
using System .Diagnostics;
using System . Runtime . InteropServices;
using System . Runtime . InteropServices . ComTypes;
using System . Diagnostics . Contracts;
using System . Windows . Controls . Ribbon;
using Microsoft . Office . Tools . Excel;
using Microsoft . Office . Tools . Ribbon;
using System . ComponentModel . Design;
using System . Reflection;
using Microsoft . Office . Interop . Access;

private static void ExcelChops ( )
        {
            Process [ ] Running = Process . GetProcessesByName ( "Excel" );
            if ( Running . Count()==0 )
            {
                return;
            }

            Microsoft . Office . Interop . Excel . Application ExcelApplication = ( Microsoft . Office . Interop . Excel . Application ) Marshal . GetActiveObject ( "Excel.Application" );
            if ( ExcelApplication == null )
            {
                return;
            }

            string ActiveExcelApplicationCaption = ExcelApplication . Caption;
            Windows ExcelWindows = ExcelApplication . Windows;
            int ExcelWindowCount = ExcelWindows . Count;
            XlWindowState WindowState = ExcelApplication . WindowState;
            Window ExcelWindow = ExcelApplication . Windows [ 1 ];
            String ExcelWindoWindowCaption = ExcelWindow . Caption;

            System . Diagnostics . Debug . WriteLine ( String . Format ( "\nExcel Application Caption {0} " , ActiveExcelApplicationCaption ) );
            System . Diagnostics . Debug . WriteLine ( String . Format ( "\nExcel Window Caption {0} " , ExcelWindoWindowCaption ) );
            System . Diagnostics . Debug . WriteLine ( String . Format ( "Excel Window Count {0} " , ExcelWindowCount ) );
            System . Diagnostics . Debug . WriteLine ( String . Format ( "Excel Window State {0} " , WindowState ) );
            //Microsoft.Office.Interop.Excel.Panes panes = ExcelWindow . Panes;
            //IteratePanes ( panes );

            Microsoft.Office.Interop.Excel.MenuBar aMB = ExcelApplication . ActiveMenuBar;
            IterateMenus ( aMB , 0 );
        System . Diagnostics . Debug . WriteLine ( String . Format ( "{0} {1} " , "Completed" , ( ( ( System . Environment . StackTrace ) . Split ( '\n' ) ) [ 2 ] . Trim ( ) ) ) );

        }
    private static void IterateMenus ( MenuBar aMB , int v )
    {

        string caption = aMB . Caption;
        int ndx = aMB . Index;
        dynamic parent = aMB . Parent;
        Menus menus = aMB . Menus;
        int menusCount = aMB . Menus . Count;

        for ( int i = 1 ; i <= menusCount ; i++ )
        {
            Menu a = menus [ i ];
            int b = a . Index;
            string c = a . Caption;
            System . Diagnostics . Debug . WriteLine ( String . Format ( "{0} {1} " , b , c ) );
            IterateMenus ( a , v + 1 );
        }

    }

    private static void IterateMenus ( Menu A , int v )
    {
        string caption = A . Caption;
        int ndx = A . Index;
        MenuItems items = A . MenuItems;
        int itemsCount = items . Count;

        for ( int i = 1 ; i <= itemsCount ; i++ )
        {
            dynamic a = items [ i ];
            Type t = a.GetType ( );

            object o = a as object;
            Type to = o . GetType ( );
            String oo = to . ToString ( );
            var occ = to . Name;
            var ooc = to . TypeHandle;

            System . Diagnostics . Debug . WriteLine ( String . Format ( "menu item {0} of {1} {2} {3} " , i , itemsCount, occ, caption) );
        }
    }

【问题讨论】:

    标签: c# excel com ribbon dynamictype


    【解决方案1】:

    功能区无法像您希望的那样简单地以编程方式控制。

    在功能区之前,Office 应用程序可以访问 MenuBar(Excel 未记录)和 CommandBar 对象。 MenuBar 是经典的菜单类型(文件、编辑、视图、窗口、帮助等)。 CommandBar 是经典的工具栏类型(菜单下方的按钮行)。使用这些对象,您可以直接操作这些旧版 UI 功能。

    丝带完全不同。使用功能区,您无法任意操作它。这是为了保护一个加载项免受另一个加载项的影响。为了使用功能区,您必须有一个加载项来提供描述您要应用的功能区配置的 XML。有几种方法可以创建 Excel 加载项:

    除此之外,我建议您在 Google 上搜索“excel 插件功能区”,以获取有关如何在插件中使用功能区的各种文档。

    MenuBarCommandBar 对象和属性仍然存在,用于传统和非功能区用途(例如,显示右键菜单)。如果您在具有功能区的 Excel 版本中创建新的应用程序级命令栏,新的命令栏会被毫不客气地转储到一个通用选项卡中,所有加载项的命令栏都会在该选项卡中结束。调整内置 CommandBars 不会影响内置功能区。

    【讨论】:

    • 我相信这是可以做到的,因为我看到其他供应商将他们的私有选项卡安装到功能区上的内置选项卡中。
    • @drdbkarron 是的,可以这样做,但不能使用您询问的 API。您必须使用 Ribbon XML 才能使用功能区。
    • 我需要一个线索。如何在运行时使用 XML 做我想做的事?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-26
    • 1970-01-01
    • 2020-07-22
    • 2010-12-24
    • 1970-01-01
    • 1970-01-01
    • 2012-09-11
    相关资源
    最近更新 更多