Эту статью написал Никита Шишкин, инженер группы водоснабжения и водоотведения отделения инженерного проектирования IBS. С его любезного согласия, я публикую данную статью в своём блоге, с небольшими правками. Статья написана для Revit 2021, для остальных версий, всё будет аналогично.
Данная статья является продолжением статей по созданию и оформлению пользовательской панели на ленте инструментов в Revit.
В статье предложены решения по созданию объектов класса PushButton (кнопки), которые расположены в стеке, с возможностью изменения размера кнопок на панели и скрытия описания напротив них.
Введение
Как выглядят подобные кнопки? На вкладке Изменить и одноименной панели находятся два типа данных кнопок:
Тип 1 представляет собой стек, состоящий из двух кнопок класса PushButton. Их особенностью является увеличенный размер самой кнопки, которой можно задать иконку размером 24х24 или 32х32 пикселя.
Тип 2 — это стек, состоящий из трех кнопок с уже меньшим размером.
Общей особенностью обоих типов является отсутствие текста напротив кнопки.
Камнем преткновения для создания подобных кнопок является невозможность гибкой настройки с помощью библиотеки RevitAPIUI и пространства имен Autodesk.Revit.UI. Вы не сможете увеличить размер кнопки или скрыть её описание. При попытке задания свойства Text для объекта класса PushButtonData строкой нулевой длины получаем исключение:
О чем собственно заранее нас и предупреждает Revit API, если посмотреть свойство ItemText в классе RibbonItem:
"The text can be changed at run time. a null reference or empty string is not allowed"
Однако, можно добавить спецсимвол, тогда текст исчезнет и плагин загрузится корректно, но только кнопка приобретёт форму прямоугольную, а не квадратную, потому что символ будет отображаться напротив кнопки. В качестве спецсимвола можно добавить пробел нулевой ширины "\u200B".
var buttonData1 = new PushButtonData(buttonName1, "\u200B", assemblyLocation, typeof(ExampleCommand).FullName);
Это не наш метод.
Использование библиотеки AdWindows
На помощь приходит библиотека AdWindows с пространством имен Autodesk.Windows. Она позволяет не только получить доступ к ленте Revit, но и управлять ею.
Добавляем новую ссылку в ваш проект:
Создаем псевдоним, поскольку Autodesk.Revit.UI использует классы с теми же именами, что и Autodesk.Windows:
using AW= Autodesk.Windows;
Создаем пользовательские вкладку New Tab, панель Solution#1 и кнопки buttonData1..5, затем добавляем кнопки на панель через метод AddStackedItems.
Использую простой код, чтобы начинающим был более понятен. Те, кто поопытнее вполне могут создать собственные методы или классы, а даже и библиотеки. Например ricaun.Revit.UI от Luiz Henrique Cassettari (ricaun). С видеодемонстрацией можно ознакомиться тут.
Впрочем, у него закрытый исходный код, так что сложно понять, как работает эта библиотека (надо читать декомпилированный код в VS), но по видеоразбору и документации к nuget можно узнать, что именно она делает. Есть и open-source решения, например, RevitExtensions от Романа Nice3Point, входящие в его открытый шаблон плагина с автоматической сборкой msi, развёртыванием релиза на GitHub и многими другими фишками (Прим. ред.)
Теперь создаем пользовательский метод, который будет искать кнопку, которая находится на определённой вкладке и панели. RibbonItem в данном случае будет являться PushButton.
Что делает метод? Он обращается к менеджеру компонентов, который предоставляет ленту инструментов Revit. Далее находит ту вкладку, которую ему указали. Обращаясь к свойству Source каждой панели на вкладке, метод получит не только те элементы, которые находятся на этих панелях, но и названия панелей.
Ключевой частью пользовательского метода является метод FindItem класса RibbonPanel, который возвращает элемент панели, чей Id совпадает с указанным Id.
Как выглядит Id у элемента на ленте Revit? Он имеет нечисловые значения, которые мы привыкли видеть в модели, и начинается с CustomCtrl_%CustomCtrl_%. В качестве разделителя между элементами ленты используется %.
Для наглядности воспользуемся надстройкой RevitLookup и найдем нашу кнопку. Открываем Dashboard и переходим в ComponentManager.
Далее ищу значение RevitRibbonControl и проваливаюсь в него. Затем выбираю RibbonTabCollection, после чего нажимаю на панель New Tab и прокручиваю до значения RibbonPanelCollection => RibbonPanelSource, после чего дважды переходим в RibbonItemCollection, а там выбираем любую кнопку и смотрим какое у нее Id. В моем случае Id будет равно CustomCtrl_%CustomCtrl_%New Tab%Solution#1%ButtonTest1.
Дело остаётся за малым. Применяем метод и меняем свойства у полученных кнопок:
Копируем файл .addin и библиотеку .dll из нашей сборки в целевую папку Revit, расположенную по пути: %ProgramData%\Autodesk\Revit\Addins\2021
После чего запускаем Revit и наблюдаем на пользовательской панели Solution#1 два стека кнопок.
В первом стеке находится пара кнопок buttondata1 и buttondata2 с размером иконки равному 24х24 и 32х32 соответственно. Не рекомендую для такой пары использовать изображение 24х24, поскольку габариты самой кнопки больше чем у изображения.
Во втором стеке привычные кнопки маленького размера, за одним исключением – у них скрыто отображение свойства Text.
Заключение
В заключении можно сказать, что библиотека AdWindows позволяет настроить оформление элементов ленты Revit, которое недоступно стандартными инструментами Revit UI. В частности, можно создать кнопки с увеличенным размером и скрыть описание кнопки.
Итоговый код в репозитории Никиты на GitHub
Заключение от автора блога
Пару недель назад Никита написал мне в личку с вопросом, описанным в данной статье. Я сказал ему, куда копать, и предложил написать гайд, если получится. У Никиты получилось, он молодец, и теперь вы тоже знаете, как решить этот вопрос.
Напоминаю про свой телеграм-канал о Revit API. Подписывайтесь на него и успехов в изучении программирования. До новых встреч!