Как задать RibbonItem.IsChecked после переключения рабочего пространства?

Автор Тема: Как задать RibbonItem.IsChecked после переключения рабочего пространства?  (Прочитано 9072 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Тема содержит сообщение с Решением. Нажмите здесь чтобы посмотреть его.

Оффлайн Дмитрий ЗагорулькинАвтор темы

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
В продолжение этой темы: http://adn-cis.org/forum/index.php?topic=3046.0
Теперь при запуске AutoCAD нужные кнопки на ленте переключаются в режим "включено". Но при переключении рабочего пространства (изменение WSCURRENT) никак не удается сделать то же самое. Я подписался на событие Application.SystemVariableChanged для отслеживания изменения WSCURRENT, но это не помогло по следующей причине. После смены пространств вкладки ленты (объект Autodesk.Windows.RibbonTab), которые еще не были посещены (свойство RibbonTab.IsVisited == false), не содержат ни одной панели (RibbonTab.Panels.Count == 0)! Панели и кнопки на них формируются только после "посещения" вкладки. Дополнительно пробовал обрабатывать событие Application.Idle - не помогло. Подскажите, как с этим справиться?
На всякий случай - как я ищу кнопки на ленте:
Код - C# [Выбрать]
  1. /// <summary>
  2. /// Получение элементов управления на ленте по идентификатору
  3. /// </summary>
  4. /// <param name="itemId">Идентификатор элемента управления</param>
  5. /// <param name="activeTabOnly">
  6. /// True - только активные вкладки, false - все вкладки
  7. /// </param>
  8. /// <returns>
  9. /// Массив найденных на ленте элементов с указанным идентификатором.
  10. /// Если не найдены - пустой массив. Если лента не загружена - null.
  11. /// </returns>
  12. public static RibbonItem[] GetAllItems(string itemId, bool activeTabOnly)
  13. {
  14.     // Список для сбора элементов
  15.     List<RibbonItem> itemsList = new List<RibbonItem>();
  16.  
  17.     // Объект ленты
  18.     RibbonControl ribCntrl = Autodesk.Windows.ComponentManager.Ribbon;
  19.  
  20.     // Если лента не загружена
  21.     if (ribCntrl == null)
  22.     {                
  23.         return null;
  24.     }
  25.  
  26.     // Вкладки ленты
  27.     IEnumerable<RibbonTab> tabs = activeTabOnly ?
  28.         ribCntrl.Tabs.Where(item => item.IsActive)
  29.         : ribCntrl.Tabs;
  30.  
  31.     // Проходим по вкладкам ленты
  32.     foreach (RibbonTab ribTab in tabs)
  33.     {      
  34.         // Проходим по панелям вкладки
  35.         foreach (RibbonPanel panel in ribTab.Panels)
  36.         {
  37.             // Ищем на панели элемент с заданным идентификатором
  38.             RibbonItem ribItem = panel.FindItem(itemId, true);
  39.             // Если нашли
  40.             if (ribItem != null)
  41.             {
  42.                 // Добавляем в список
  43.                 itemsList.Add(ribItem);
  44.             }
  45.         }
  46.     }
  47.    
  48.     return itemsList.ToArray();
  49. }
  50.  

Оффлайн Александр Пекшев aka Modis

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
А при изменении WSCURRENT вы перестраиваете Ribbon?

Оффлайн Дмитрий ЗагорулькинАвтор темы

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Не совсем понял вопрос. Я программно ленту не строю, не перестраиваю. У меня есть CUIX - файл частичной адаптации с моей вкладкой, несколькими панелями и порядка 40 кнопок на них. Этот файл я подгружаю с помощью Bundle.

Оффлайн Александр Пекшев aka Modis

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Не могу утверждать, ибо сто лет не работал с CUI, но когда строишь ленту программно, то свою вкладку при изменении WSCURRENT нужно перестраивать. Может и CUI нужно заново прогружать?

Оффлайн Дмитрий ЗагорулькинАвтор темы

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Да нет, меню подгружено, вкладка находится, так что, перезагружать не надо ничего. Более того, если вкладку сделать активной программно (RibbonItem.IsActive == true) - панели и кнопки формируются. Но идея проходить по всей ленте и активировать вкладки мне не очень нравится.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Но идея проходить по всей ленте и активировать вкладки мне не очень нравится.
Похоже это единственный вариант.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий ЗагорулькинАвтор темы

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Да я вроде бы накопал еще один вариант. Если после смены WSCURRENT подписываться на событие Autodesk.Windows.ComponentManager.Ribbon.BackgroundRenderFinished и после него уже менять свойства RibbonItem - все получается, правда, с небольшой задержкой. Буду тестировать.

Отмечено как Решение Дмитрий Загорулькин 25-09-2015, 18:11:17

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Теоретически ты можешь подписаться на событие RibbonTab.Activated и в нём при необходимости менять RibbonItem.IsChecked
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий ЗагорулькинАвтор темы

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Это подойдет, если отслеживать какую-то определенную вкладку. Но тогда, если пользователь вынесет кнопку на какую-то другую вкладку, изменение ее состояния не будет работать. Или пробегать по всем вкладкам, цеплять к ним обработчики этого события и при их активации искать кнопки? Как-то это сложно получается...

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Или пробегать по всем вкладкам, цеплять к ним обработчики этого события и при их активации искать кнопки? Как-то это сложно получается...
Если не найдёшь другой способ, то мне кажется этот вполне приемлемым. Когда-то я использовал аналогичный способ, но с тулбарами обычного меню для панелей слоёв, типов и весов линий, имён текстовых и размерных стилей, и т.д., когда нужно было заставить их отображать текущее состояние в чертеже.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий ЗагорулькинАвтор темы

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
При использовании Autodesk.Windows.ComponentManager.Ribbon.BackgroundRenderFinished никак не удалось побороть задержку обработки:

При использовании RibbonTab.Activate все гораздо лучше: