Найти тему

Обработка событий в Revit API

Оглавление

Всем привет! Сегодня поговорим о том, что такое события и что мы можем с ними сделать. Я уже немного рассказывал что-то похожее в статье про обработку встроенных ошибок, а также в контексте событий Windows Forms (событие нажатия на кнопку) но сегодня рассмотрим этот большой блок по-настоящему.

Определение

Если честно, определение События кажется таким очевидным, что у меня возникли затруднения с его формулировкой. Что ж, событие — это некоторая ситуация, однозначно описанная в каком либо классе и возникающая при выполнении программного кода. Мы можем подписаться на событие, и тогда при его возникновении произойдут некоторые действия.

Также мы можем сами определять и вызывать события в своём классе. И мы это даже уже делали в цикле о WPF-приложениях:

Мы определили событие в классе ViewModel ключевым словом event, назначили ему тип EventHandler, который представляет собой встроенный делегат.

Делегат — это описание метода без реализации. В данном случае у нас метод, который ничего не возвращает (void), и принимает 2 аргумента: object и EventArgs. Мы можем подписаться на это событие: добавить к нему сколько угодно методов с данной сигнатурой.

Как найти события в Revit

Непонятно? Попробуйте посмотреть эту статью, ну или просто читайте дальше: посмотрим на практике.

Итак, где мы можем найти события? Конечно же, на revitapidocs:

Вот событие "Документ сохранён"
Вот событие "Документ сохранён"

А также с помощью Revit Lookup (обязательно ставьте себе новую версию). Там есть встроенный EventMonitor, где мы можем изучать произошедшие события и отличать одно от другого (для наших целей).

Только событие Idling нельзя отследить, оно происходит условно всегда, когда в программе не происходит ничего. Будьте осторожны с ним и не забивайте его сложной (а лучше вообще никакой) логикой.

-3

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

Пример

Давайте отследим событие показа диалогового окна и закроем его методом OverrideResult. Итак, поехали:

У нашего приложения есть событие DialogBoxShowingEvent. Подпишемся на него там, где мы имеем доступ к UIControlledApplication — в нашем IExternalApplication:

Мучаться с именем метода не нужно: VS сама предложит вам назвать его так
Мучаться с именем метода не нужно: VS сама предложит вам назвать его так

Далее вызовем в ревите интересующее нас окно и посмотрим в лукапе, какое событие возникло. У меня это будет диспетчер макросов:

-5

Мы получили DialogId. С его помощью мы отсортируем события, одно от другого:

-6

На строке 46 я написал код, который закроет диспетчер. Я закомментировал его, чтоб никто случайно не сломал себе диспетчер макросов, скачав моё приложение с гитхаба.

На всякий случай, код этой статьи на гитхаб я отправлю в закомментированном виде, чтобы никому случайно потом ничего не сломать.

На 47 строке мы выводим TaskDialog. Будьте осторожны, если в обработчике этого события вызывать TaskDialog, то получите зацикливание (новое событие, новое окно), и вылет Ревита. Я тут избегаю этого с помощью проверки DialogId.

В общем-то, и всё. Примерно таким нехитрым способом можно обрабатывать события в Revit на базовом уровне.

Итоговый закомментированный код на Гитхабе.

Напоминаю, что у меня есть телеграм-канал — буду рад видеть вас там. До новых встреч!

-7