MyTetra Share
Делитесь знаниями!
12. Динамическое меню.
Время создания: 16.03.2019 23:24
Текстовые метки: Ribbon XML Editor
Раздел: Разные закладки - MSO - Ribbon XML Editor
Запись: xintrea/mytetra_db_adgaver_new/master/base/1526206098ne4zxutz0s/text.html на raw.githubusercontent.com

Теперь мы уже почти профессионалы в программировании интерфейсов, и можем замахнуться аж на динамическое меню. Динамическое меню, как и динамические атрибуты, получает своё содержимое из функции обратного вызова. То есть, наша функция должна возвращать некий XML-код, который и будет формировать дочерние элементы меню.

Давайте сделаем ещё одну надстройку-демонстратор динамического меню. Создадим третий документ и откроем его в Ribbon XML Editor. Построим в нём следующий код:


<?xml version="1.0" standalone="yes"?>

<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui" xmlns:МПИ="http://customui.blogspot.ru">

    <ribbon startFromScratch="false">

        <tabs>

            <tab idQ="МПИ:Вкладка1" label="Полезные надстройки" insertBeforeMso="TabHome" keytip="Н">

                <group id="ДинамическиеМеню" label="Демонстрация меню">

                    <menu id="Меню1" label="Обычное меню" itemSize="large">

                        <button

id="Кнопка1"

label="Пункт 1"

description="Пункт обычного меню"

onAction="Сообщение1" />

                        <button

id="Кнопка2"

label="Пункт 2"

description="Пункт обычного меню"

onAction="Сообщение2" />

                        <button

id="Кнопка3"

label="Пункт 3"

description="Пункт обычного меню"

onAction="Сообщение3" />

                    </menu>

                    <dynamicMenu

id="ДинамическоеМеню1"

label="Динкамическое меню"

getContent="ВернутьДинамическоеМеню" />

                </group>

            </tab>

        </tabs>

    </ribbon>

</customUI>




В этом коде мы создаём на нашей вкладке третью группу, в которой размещаем обычное меню с тремя пунктами и динамическое меню, пункты которого мы будем получать с помощью функции «ВернутьДинамическоеМеню». Сгенерируем шаблоны функций обратного вызова и сохраним их в файле, как мы уже делали это ранее.

Кстати, если вы хотите изменить имя, предлагаемое по умолчанию, под которым сохраняются шаблоны функций, зайдите в настройки Ribbon XML Editor, и обратите внимание на окно в правом верхнем углу. Этот блок текста каждый раз помещается в начало сохраняемого файла, и вы можете отредактировать его по вашему усмотрению. В первой строке написано:


Attribute VB_Name = "RibbonCallbacks"


Мы можем поменять эту строку на:


Attribute VB_Name = "CustomUICallbacks"


и при сохранении файла нам будет предлагаться уже новое имя.

Итак, запустим документ на выполнение. Обычное меню уже работает, а для формирования пунктов динамического меню нам нужно открыть редактор Бейсика (Alt+F11) и загрузить в него модуль с сохранёнными нами ранее шаблонами функций обратного вызова.

Заполним шаблоны функций следующим кодом:


'Кнопка1 (компонент: button, атрибут: onAction), 2007

Sub Сообщение1(control As IRibbonControl)

MsgBox "Был выбран пункт 1"

End Sub


'Кнопка2 (компонент: button, атрибут: onAction), 2007

Sub Сообщение2(control As IRibbonControl)

MsgBox "Был выбран пункт 2"

End Sub


'Кнопка3 (компонент: button, атрибут: onAction), 2007

Sub Сообщение3(control As IRibbonControl)

MsgBox "Был выбран пункт 3"

End Sub


'ДинамическоеМеню1 (компонент: dynamicMenu, атрибут: getContent), 2007

Sub ВернутьДинамическоеМеню(control As IRibbonControl, ByRef content)

Dim sXML As String

sXML = "<menu itemSize=""large"" xmlns=""http://schemas.microsoft.com/office/2006/01/customui"">" & vbCrLf

sXML = sXML & "<button id=""Кнопка1"" label=""Пункт 1"" description=""Пункт динамического меню"" onAction = ""Сообщение1""/>" & vbCrLf

sXML = sXML & "<button id=""Кнопка2"" label=""Пункт 2"" description=""Пункт динамического меню"" onAction = ""Сообщение2""/>" & vbCrLf

sXML = sXML & "<button id=""Кнопка3"" label=""Пункт 3"" description=""Пункт динамического меню"" onAction = ""Сообщение3""/>" & vbCrLf

content = sXML & "</menu>"

End Sub




В первых трёх функциях мы просто выводим сообщение о нажатии того или иного пункта, а в последней — формируем пункты, которые должны будут вернуться из функции во время выполнения документа. Тут требуются небольшое пояснение.

Формируемые пункты возвращаются в динамическое меню не списком, а XML-структурой, объединенённой корневым элементом menu, имеющим тип CT_MenuRoot. Элемента этого типа нет в иерархии статических элементов. Но в справке Ribbon XML Editor среди приложений мы можем найти ссылку «Динамическое меню», нажав на которую, мы откроем страничку с описанием этого типа и дополнительными сведениями по нему.

Согласно справке, корневой элемент menu должен содержать атрибут xmlns с объявлением пространства имён, используемое нами в основном коде. Замечу, что несмотря на то, что ранее мы использовали этот атрибут только в корневом элементе customUI, теоретически его можно использовать в любом элементе интерфейса, хотя его и не будет среди предлагаемых вариантов в автодополнении ввиду редкости такого использования. В данном случае мы применяем его в элементе menu.

В функции «ВернутьДинамическоеМеню» мы присваиваем строковой переменной sXML сначала открывающий тег menu с атрибутом размера пунктов меню и объявлением пространства имён, затем добавляем туда коды перевода строки (vbCrLf), затем теги элементов пунктов меню с желаемыми атрибутами и, в завершение, присваиваем возвращаемой переменной содержимое полученной строки с добавлением закрывающего тега menu. Внутри строковых переменных знак кавычек делается сдвоенным, чтобы не было конфликта с синтаксисом Бейсика, использующего тот же знак для обозначения строк.

Сохраняем код, закрываем редактор Бейсика, потом документ, а затем снова открываем его и нажмём на кнопку открытия динамического меню. В момент нажатия срабатывает код формирования меню, и оно отображается. Сравните его работу с работой рядом расположенного статического меню.


9 комментариев:

Александр Витер 04 апреля, 2015 23:57

Динамическое меню получает свой контент не при открытии документа, а при своём открытии. Именно с этим связана небольшая задержка при открытии насыщенных стандартных меню, вроде галереи стилей, номеров страниц и т.п.

Очень хороший материал у вас. По-доброму завидую :)

dolbodub 05 апреля, 2015 00:08

Спасибо, поправил.

Благодарю за положительный отзыв! )


Анонимный 08 апреля, 2015 19:38

Спасибо за полезную информацию. Есть у меня такой вопрос. Судя по всему функция ВернутьДинамическоеМеню вызывается только один раз при первом обращении. Как сделать, чтобы она вызывалась каждый раз, когда открывают динамическое меню? Это было бы полезно, когда меню зависит от каких-нибудь условий.


dolbodub 08 апреля, 2015 20:52

Я не знаю... спросите у Александра Витера (предыдущий комментарий), он, судя по всему, знает про динамическое меню побольше моего.

Александр Витер 09 апреля, 2015 19:32

Нужно обновлять ленту методом Invalidate или отдельный элемент управления Invalidate(control.Id)

Почитайте мой блог, посвящённый настройке интерфейса. Я как раз подвёл итог работе с динамическими меню: Элемент управления dynamicMenu


Алексей Мальков 28 октября, 2015 12:45

Скажите, а как называется и настраивается элемент интерфейса в виде текстового поля с кнопками увеличить и уменьшить значение?

Как стандартный элемент для задания интервала между строками, например


dolbodub 28 октября, 2015 14:37

Это который на вкладке "разметка страницы? Интересный вопрос... В распоряжении пользователя такого элемента нет. Как и, по моему, некоторых других составных элементов, имеющихся на стандартных лентах. Сами применяют, а нам не дают (((

Алексей Мальков 28 октября, 2015 16:54

Нагуглил такое решение проблемы:

https://social.msdn.microsoft.com/Forums/office/en-US/04dd2304-26e8-44dc-b2c8-2fc541738e86/how-to-add-a-spinner-spin-box-control-to-a-custom-ribbon-in-excel-2007?forum=exceldev


dolbodub 28 октября, 2015 17:37

Ну да, только если так - текстовое поле и справа две стандартные кнопки, расположенные горизонтально.

Спасибо за ссылку!


Так же в этом разделе:
 
MyTetra Share v.0.65
Яндекс индекс цитирования