简体   繁体   English

如何在运行时连接到办公室流利的功能区并在c#中添加/操作功能区选项卡?

[英]How do I connect to an office fluent ribbon at runtime and add/manipulate a ribbon tab in c#?

I want to connect to a running excel, or launch excel, and at run time add a tab on the root / main ribbon /menubar. 我想连接到运行中的excel,或启动excel,然后在运行时在根目录/主功能区/菜单栏上添加一个选项卡。 When I connect with interop to the excel application object I see a dynamic object menubar. 当我与interop连接到excel应用程序对象时,我会看到一个动态对象菜单栏。 It resolves at runtime to a .com object that I can't parse. 它在运行时解析为我无法解析的.com对象。

I can iterate into each menu and see menu.name, ID, and menu item. 我可以迭代到每个菜单,然后查看menu.name,ID和菜单项。 It looks like the ribbon items in my running excel, but i can't add or remove or influence items at run time. 它看起来像我正在运行的excel中的功能区项目,但我无法在运行时添加或删除或影响项目。 The menus, menu, menuitem are all Microsoft private. 菜单,菜单,菜单项都是Microsoft私有的。 What am i missing to resolve and add/manipulate/remove my own runtime menu items? 我缺少什么来解决和添加/操作/删除自己的运行时菜单项? I don't want to write and compile static or runtime xml (yet). 我不想编写和编译静态或运行时xml(尚未)。 I see other vendors do this. 我看到其他供应商也这样做。 What assembly or include am i missing? 我缺少什么大会或包括? Here is what I have from pure hacking it out. 这就是我纯粹破解它所拥有的。

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

The ribbon cannot be programmatically controlled as simply as you would hope. 功能区不能像您希望的那样通过编程方式控制。

Prior to the ribbon, Office applications had access to MenuBar (undocumented for Excel) and CommandBar objects. 在功能区之前,Office应用程序可以访问MenuBar (对于Excel未记录)和CommandBar对象。 A MenuBar is the classic type of menu (File, Edit, View, Window, Help, etc). MenuBar是经典的菜单类型(文件,编辑,视图,窗口,帮助等)。 A CommandBar is the classic type of toolbar (rows of buttons below the menu). CommandBar是经典的工具栏类型(菜单下方的按钮行)。 With these objects, you could directly manipulate these legacy UI features. 使用这些对象,您可以直接操作这些旧版UI功能。

The ribbon is entirely different. 功能区完全不同。 With the ribbon, you are not given the ability to arbitrarily manipulate it. 使用功能区,您将无法任意操作它。 This is intended to protect one add-in from another. 这是为了保护一个外接程序不受另一个外接程序的影响。 In order to work with the ribbon, you must have an Add-In to provide XML describing the ribbon configuration you'd like to apply. 为了使用功能区,您必须具有一个加载项以提供描述您要应用的功能区配置的XML。 There are a few ways to create an Excel add-in: 有几种创建Excel加载项的方法:

Beyond that, I suggest you google for "excel addin ribbon" for various documentation on how to work with the ribbon from within your addin. 除此之外,我建议您在Google上搜索“ excel插件功能区”,以获取有关如何从插件中使用功能区的各种文档。

The MenuBar and CommandBar objects and properties are still around for legacy and non-ribbon purposes (eg displaying a right-click menu). MenuBarCommandBar对象和属性仍然存在,以实现传统功能和非功能性目的(例如,显示右键菜单)。 If you create new Application-level CommandBars in versions of Excel that have a ribbon, the new CommandBars are unceremoniously dumped into a generic tab where all the add-ins' CommandBars end up. 如果您在具有功能区的Excel版本中创建新的应用程序级命令栏,则新命令栏会毫不客气地转储到通用选项卡中,所有外接程序的命令栏都将在其中结束。 Tweaking the built-in CommandBars isn't going to affect the built-in ribbon. 调整内置CommandBar不会影响内置功能区。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM