{"id":17335149,"url":"https://github.com/nice3point/optionsbar","last_synced_at":"2025-08-01T11:31:47.691Z","repository":{"id":195402142,"uuid":"692381316","full_name":"Nice3point/OptionsBar","owner":"Nice3point","description":"Revit OptionsBar samples","archived":false,"fork":false,"pushed_at":"2023-09-18T10:44:01.000Z","size":66,"stargazers_count":17,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-07T20:42:59.171Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Nice3point.png","metadata":{"files":{"readme":"Readme.md","changelog":"Changelog.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-09-16T10:04:00.000Z","updated_at":"2025-03-11T06:33:47.000Z","dependencies_parsed_at":null,"dependency_job_id":"da7eeb9e-820d-4aca-9537-49206c585a44","html_url":"https://github.com/Nice3point/OptionsBar","commit_stats":null,"previous_names":["nice3point/optionsbar"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/Nice3point/OptionsBar","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Nice3point%2FOptionsBar","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Nice3point%2FOptionsBar/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Nice3point%2FOptionsBar/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Nice3point%2FOptionsBar/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Nice3point","download_url":"https://codeload.github.com/Nice3point/OptionsBar/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Nice3point%2FOptionsBar/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":268215576,"owners_count":24214363,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-01T02:00:08.611Z","response_time":67,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-15T15:08:22.638Z","updated_at":"2025-08-01T11:31:46.506Z","avatar_url":"https://github.com/Nice3point.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# OptionsBar: Улучшение пользовательского опыта в Revit\n\n[Revit](https://www.autodesk.com/products/revit/overview) - это мощное инструментальное средство для проектирования и моделирования зданий, и, безусловно, высокая эффективность работы с этим программным обеспечением является ключевым аспектом для успешных проектов. \nОдним из инструментов, способствующих этой эффективности, является OptionsBar, но мало кто знает о его возможностях и том как его настроить.\n\n# Введение в OptionsBar\n\n[OptionsBar](https://help.autodesk.com/view/RVT/2024/ENU/?guid=GUID-28BDE98C-E8A9-4C74-8ABC-9DABD13163D9) - это удобная панель инструментов в Revit, которая обладает огромным потенциалом. \nОна предоставляет возможности, начиная от добавления собственных инструментов на ленту инструментов и заканчивая отображением информации о работе ваших собственных надстроек. \nОднако, документация по Revit API не предоставляет достаточно информации о том, как использовать OptionsBar в полной мере.\n\n![](https://help.autodesk.com/cloudhelp/2024/ENU/Revit-GetStarted/images/GUID-CCF99547-F6D8-4A0F-908C-49BA85BF3C49.png)\n\n# Начало работы\n\nПрежде чем мы начнем настраивать OptionsBar, нам потребуется добавить необходимые зависимости и создать контроллер для управления этой панелью.\n\nИспользованные технологии:\n\n- Язык - C#\n- UI framework - WPF\n\n# Настройка OptionsBar. Шаг за Шагом\n\nДавайте подробно рассмотрим процесс настройки OptionsBar и как это можно сделать максимально эффективным образом.\n\n## Шаг 1: Добавление Зависимостей\n\nПонимание того, что пользовательский интерфейс в Revit реализован с использованием технологии WPF (Windows Presentation Foundation), помогает нам получить доступ ко всем элементам интерфейса.\nДля этого нам понадобится библиотека `AdWindows.dll`, которая поставляется с Revit. \n\nДля компиляции проекта на любом устройстве добавим NuGet пакет в .csproj файл проекта следующим образом:\n\n```xml\n\u003cItemGroup\u003e\n    \u003cPackageReference Include=\"Nice3point.Revit.Api.AdWindows\" Version=\"$(RevitVersion).*\"/\u003e\n\u003c/ItemGroup\u003e\n```\n\n## Шаг 2: Создание Контроллера\n\nДля того чтобы управлять OptionsBar, нам потребуется контроллер, который будет обрабатывать его отображение и скрытие. Для доступа к ленте инструментов Revit и OptionsBar мы воспользуемся статическим свойством `ComponentManager.Ribbon` из библиотеки `AdWindows.dll`, которую мы подключили на предыдущем шаге.\n\nПроцесс настройки OptionsBar можно разбить на следующие этапы:\n\n1. Поиск встроенной панели\n2. Создание пользовательской панели\n3. Скрытие/отображение встроенной и пользовательской панели\n\nВажно заметить, что мы не удаляем или не заменяем встроенную панель OptionsBar, чтобы не нарушить функциональность Revit. \nВместо этого мы просто скрываем ее и отображаем собственную панель, когда это необходимо.\n\nДавайте рассмотрим пример кода, который позволяет отображать и скрывать пользовательскую панель:\n\n```C#\npublic static class RibbonController\n{\n    private static readonly Grid RootGrid;\n    private static ContentPresenter _panelPresenter;\n    private static readonly FrameworkElement InternalToolPanel;\n\n    static RibbonController()\n    {\n        RootGrid = VisualUtils.FindVisualParent\u003cGrid\u003e(ComponentManager.Ribbon, \"rootGrid\");\n        if (RootGrid is null) throw new InvalidOperationException(\"Cannot find root grid in Revit UI\");\n\n        InternalToolPanel = VisualUtils.FindVisualChild\u003cDialogBarControl\u003e(RootGrid, string.Empty);\n        if (InternalToolPanel is null) throw new InvalidOperationException(\"Cannot find internal tool panel in Revit UI\");\n    }\n\n    public static void ShowOptionsBar(FrameworkElement content)\n    {\n        if (_panelPresenter is not null)\n        {\n            _panelPresenter.Content = content;\n            _panelPresenter.Visibility = Visibility.Visible;\n            InternalToolPanel.Height = 0;\n            return;\n        }\n\n        _panelPresenter = CreateOptionsBar();\n        _panelPresenter.Content = content;\n\n        InternalToolPanel.Height = 0;\n    }\n\n    public static void HideOptionsBar()\n    {\n        if (_panelPresenter is null) return;\n\n        _panelPresenter.Content = null;\n        _panelPresenter.Visibility = Visibility.Collapsed;\n\n        InternalToolPanel.Height = 26;\n    }\n\n    private static ContentPresenter CreateOptionsBar()\n    {\n        const int panelRow = 2;\n\n        RootGrid.RowDefinitions.Insert(2, new RowDefinition\n        {\n            Height = new GridLength(1, GridUnitType.Auto)\n        });\n\n        foreach (UIElement child in RootGrid.Children)\n        {\n            var row = Grid.GetRow(child);\n            if (row \u003e 1) Grid.SetRow(child, row + 1);\n        }\n\n        var panelPresenter = new ContentPresenter();\n        Grid.SetRow(panelPresenter, panelRow);\n        RootGrid.Children.Add(panelPresenter);\n\n        return panelPresenter;\n    }\n}\n```\n\nВ примере использованы только публичные свойства RevitApi и системные методы WPF.\nВзаимодействие с лентой реализовано  методами `ShowOptionsBar()` и `HideOptionsBar()`. Метод `ShowOptionsBar()` принимает любой FrameworkElement, который и будет отображаться для пользователя.\n\n## Шаг 3: Создание пользовательского интерфейса\n\nЧтобы создать пользовательский интерфейс для OptionsBar, мы будем использовать паттерн MVVM (Model-View-ViewModel) и фреймворк WPF (Windows Presentation Foundation).\n\nДля примера, рассмотрим простую разметку панели с текстовым полем и выпадающим списком:\n\n![изображение](https://github.com/Nice3point/OptionsBar/assets/20504884/3932ef5f-82e0-4b59-bc61-b95aef6199c8)\n\n```xml\n\u003cStackPanel\n        x:Class=\"OptionsBar.Views.OptionsView\"\n        xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n        xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n        xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n        xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n        xmlns:viewModels=\"clr-namespace:OptionsBar.ViewModels\"\n        d:DataContext=\"{d:DesignInstance Type=viewModels:OptionsViewModel}\"\n        mc:Ignorable=\"d\"\n        Background=\"#FFE5F0D7\"\n        Orientation=\"Horizontal\"\n        Height=\"26\"\n        d:DesignWidth=\"430\"\u003e\n    \u003cTextBlock\n            Margin=\"10 0 0 0\"\n            Text=\"Wall options\"\n            VerticalAlignment=\"Center\" /\u003e\n    \u003cBorder\n            Width=\"3\"\n            BorderThickness=\"1 0\"\n            BorderBrush=\"Azure\"\n            Background=\"Gray\"\n            Margin=\"10 0\" /\u003e\n    \u003cTextBlock\n            Text=\"Offset: \"\n            VerticalAlignment=\"Center\" /\u003e\n    \u003cTextBox\n            Width=\"100\"\n            Margin=\"10 1 0 1\"\n            VerticalContentAlignment=\"Center\"\n            Text=\"{Binding Offset, UpdateSourceTrigger=PropertyChanged}\" /\u003e\n    \u003cTextBlock\n            Text=\"Constraint: \"\n            Margin=\"10 0 0 0\"\n            VerticalAlignment=\"Center\" /\u003e\n    \u003cComboBox\n            Width=\"100\"\n            Margin=\"10 1 0 1\"\n            VerticalContentAlignment=\"Center\"\n            SelectedIndex=\"0\"\n            ItemsSource=\"{Binding Constraints}\" /\u003e\n\u003c/StackPanel\u003e\n```\n\nПример кода для ViewModel:\n\n```C#\npublic partial class OptionsViewModel : ObservableObject\n{\n    [ObservableProperty] private double _offset;\n    [ObservableProperty] private string[] _constraints;\n}\n```\n\nВерстка ничем не отличается от привычных WPF приложений, однако корневым элементов будет не Window, а любой контейнер по типу StackPanel, Grid и т.д., поскольку OptionBar является встраиваемым в Revit UI.\n\n## Сценарии использования\n\nOptionsBar предоставляет бесконечные возможности для оптимизации рабочего процесса в Revit. Рассмотрим некоторые из наиболее популярных сценариев использования:\n\n### Сценарий 1: Утилиты\n\nOptionsBar может быть использован для добавления пользовательских инструментов, которые могут быть удобно расположены на ленте инструментов. \nЭто особенно полезно, когда создание отдельного окна излишне.\n\n![изображение](https://github.com/Nice3point/OptionsBar/assets/20504884/10cafa43-8255-49ba-b764-7c5c0be2340a)\n\n### Сценарий 2: Опции при выборе элемента в модели\n\nЭтот сценарий охватывает ситуации, когда пользователь работает с моделью в Revit и должен выбрать определенный элемент для последующего редактирования. \nДля более удобной и интуитивно понятной настройки параметров вы можете использовать OptionsBar, вместо создания дополнительных окон.\n\nПример: Допустим, у вас есть плагин, который позволяет пользователю настраивать смещение сверху стены. Рассмотрим как расположить все инструменты на панели OptionsBar.\n\n![изображение](https://github.com/Nice3point/OptionsBar/assets/20504884/65a508ce-2f9c-414d-80b3-f996b5e679d6)\n\n- Шаг 1: Добавление OptionsBar на ленту Revit\n\n    Первым шагом в этом сценарии является настройка OptionsBar для отображения на ленте инструментов Revit.\n    Вы можете создать собственное представление (View) для OptionsBar, с параметрами, которые пользователь может настраивать.\n    \n    Пример кода, с использованием паттерна MVVM:\n    \n    ```C#\n    private OptionsViewModel SetupOptionsBar()\n    {\n        var options = new OptionsViewModel\n        {\n            Offset = 0,\n            Constraints = Document.EnumerateInstances\u003cLevel\u003e(BuiltInCategory.OST_Levels).Select(level =\u003e level.Name).ToArray()\n        };\n    \n        var view = new OptionsView(options);\n        RibbonController.ShowOptionsBar(view);\n        return options;\n    }\n    ```\n\n- Шаг 2: Выбор элемента\n\n  После настройки OptionsBar пользователь выбирает элемент в модели, с которым он хочет работать. Это может быть, например, выбор стены для настройки смещения.\n  \n  Пример кода для выбора элемента:\n  \n  ```C#\n  private Wall PickWall()\n  {\n      var selectionConfiguration = new SelectionConfiguration().Allow.Element(selection =\u003e selection is Wall);\n      var reference = UiDocument.Selection.PickObject(ObjectType.Element, selectionConfiguration.Filter, \"Select wall\");\n      return reference.ElementId.ToElement\u003cWall\u003e(Document);\n  }\n  ```\n\n- Шаг 3: Изменение параметров элемента\n\n  Теперь, когда пользователь выбрал элемент и OptionsBar настроен, можно приступить к настройке параметров элемента. \n  Значение смещение мы возьмем из ViewModel, которое ввел пользователь и зададим его параметру стены.\n  \n  Пример кода для изменения параметров элемента:\n  \n  ```C#\n  private void ModifyWall(Wall wall, OptionsViewModel options)\n  {\n      using var transaction = new Transaction(Document);\n      transaction.Start(\"Set offset\");\n      wall.GetParameter(BuiltInParameter.WALL_TOP_OFFSET)!.Set(options.Offset);\n      transaction.Commit();\n  }\n  ```\n\n- Шаг 4: Восстановление ленты Revit\n\n  После завершения настройки параметров элемента, важно скрыть OptionsBar и восстановить нормальное состояние ленты инструментов Revit. Для этого добавим `finally` блок после вызова всех методов.\n  \n  ```C#\n  public override void Execute()\n  {\n      try\n      {\n          var options = SetupOptionsBar();\n          var wall = PickWall();\n          ModifyWall(wall, options);\n      }\n      catch (OperationCanceledException)\n      {\n          // ignored\n      }\n      finally\n      {\n          RibbonController.HideOptionsBar();\n      }\n  }\n  ```\n  \n  Этот сценарий позволяет пользователям быстро и удобно настраивать параметры элементов модели без необходимости открывать дополнительные окна или выполнять лишние действия. OptionsBar делает процесс редактирования элементов более интуитивным и эффективным.\n\n### Сценарий 3: Бегущая строка\n\nХотите чего-то необычного? Бегущая строка разбавит ваши серые будни моделирования\n\n![](https://github.com/Nice3point/OptionsBar/assets/20504884/9427569b-1cce-41c8-a1f5-e88bea4c8683)\n\n## Заключение\n\nOptionsBar - это мощный инструмент в Revit, который позволяет оптимизировать рабочий процесс и сделать его более эффективным. \nНе ограничивайтесь только описанными сценариями использования - экспериментируйте, создавайте свои уникальные решения и сделайте работу в Revit еще более продуктивной.\n\nИсходный код проекта: https://github.com/Nice3point/OptionsBar\n\nТакже доступны установщики с примерами для Revit: https://github.com/Nice3point/OptionsBar/releases","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnice3point%2Foptionsbar","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnice3point%2Foptionsbar","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnice3point%2Foptionsbar/lists"}