Как подключиться к ленте Office Fluent во время выполнения и добавить/управлять вкладкой ленты в С#?

Я хочу подключиться к работающему excel или запустить excel и во время выполнения добавить вкладку в корень/основную ленту/менюбар. Когда я подключаюсь к взаимодействию с объектом приложения excel, я вижу строку меню динамического объекта. Во время выполнения он разрешается в объект .com, который я не могу проанализировать.

Я могу перебирать каждое меню и видеть menu.name, ID и пункт меню. Похоже, что элементы ленты в моем рабочем Excel, но я не могу добавлять или удалять элементы или влиять на них во время выполнения. Меню, меню, пункт меню — все это конфиденциально Microsoft. Что мне не хватает для разрешения и добавления/управления/удаления моих собственных пунктов меню во время выполнения? Я не хочу писать и компилировать статический или исполняемый 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) );
        }
    }

person dr d b karron    schedule 09.03.2019    source источник


Ответы (1)


Лента не может программно управляться так просто, как хотелось бы.

До появления ленты приложения Office имели доступ к MenuBar (недокументированному для Excel) и CommandBar объектов. MenuBar — это классический тип меню (Файл, Правка, Вид, Окно, Справка и т. д.). CommandBar — это классический тип панели инструментов (ряды кнопок под меню). С помощью этих объектов вы можете напрямую манипулировать этими устаревшими функциями пользовательского интерфейса.

Лента совсем другая. С лентой вам не дается возможность произвольно ею манипулировать. Это предназначено для защиты одной надстройки от другой. Для работы с лентой у вас должна быть надстройка для предоставления XML, описывающего конфигурацию ленты, которую вы хотите применить. Существует несколько способов создания надстройки Excel:

Кроме того, я предлагаю вам поискать в Google «ленту надстроек Excel» для получения различной документации о том, как работать с лентой из вашей надстройки.

Объекты и свойства MenuBar и CommandBar по-прежнему используются для устаревших и не связанных с лентой целей (например, для отображения контекстного меню). Если вы создаете новые панели команд уровня приложения в версиях Excel с лентой, новые панели команд бесцеремонно сбрасываются на общую вкладку, где заканчиваются все панели команд надстроек. Настройка встроенных панелей CommandBars не повлияет на встроенную ленту.

person Michael Gunter    schedule 11.03.2019
comment
Я считаю, что это можно сделать, потому что я вижу, как другие поставщики помещают свои личные вкладки во встроенные вкладки на ленте. - person dr d b karron; 31.03.2019
comment
@drdbkarron Да, это можно сделать, но не с помощью API, о которых вы спрашиваете. Вы должны использовать Ribbon XML для работы с лентой. - person Michael Gunter; 01.04.2019
comment
Мне нужна подсказка. Как я могу делать то, что хочу, с XML во время выполнения? - person dr d b karron; 02.04.2019