Всем привет! Сегодня поговорим о том, что такое события и что мы можем с ними сделать. Я уже немного рассказывал что-то похожее в статье про обработку встроенных ошибок, а также в контексте событий Windows Forms (событие нажатия на кнопку) но сегодня рассмотрим этот большой блок по-настоящему.
Определение
Если честно, определение События кажется таким очевидным, что у меня возникли затруднения с его формулировкой. Что ж, событие — это некоторая ситуация, однозначно описанная в каком либо классе и возникающая при выполнении программного кода. Мы можем подписаться на событие, и тогда при его возникновении произойдут некоторые действия.
Также мы можем сами определять и вызывать события в своём классе. И мы это даже уже делали в цикле о WPF-приложениях:
Мы определили событие в классе ViewModel ключевым словом event, назначили ему тип EventHandler, который представляет собой встроенный делегат.
Делегат — это описание метода без реализации. В данном случае у нас метод, который ничего не возвращает (void), и принимает 2 аргумента: object и EventArgs. Мы можем подписаться на это событие: добавить к нему сколько угодно методов с данной сигнатурой.
Как найти события в Revit
Непонятно? Попробуйте посмотреть эту статью, ну или просто читайте дальше: посмотрим на практике.
Итак, где мы можем найти события? Конечно же, на revitapidocs:
А также с помощью Revit Lookup (обязательно ставьте себе новую версию). Там есть встроенный EventMonitor, где мы можем изучать произошедшие события и отличать одно от другого (для наших целей).
Только событие Idling нельзя отследить, оно происходит условно всегда, когда в программе не происходит ничего. Будьте осторожны с ним и не забивайте его сложной (а лучше вообще никакой) логикой.
Тут можно посмотреть, отменяемое ли событие, и что отличается в аргументах одних событий от других.
Пример
Давайте отследим событие показа диалогового окна и закроем его методом OverrideResult. Итак, поехали:
У нашего приложения есть событие DialogBoxShowingEvent. Подпишемся на него там, где мы имеем доступ к UIControlledApplication — в нашем IExternalApplication:
Далее вызовем в ревите интересующее нас окно и посмотрим в лукапе, какое событие возникло. У меня это будет диспетчер макросов:
Мы получили DialogId. С его помощью мы отсортируем события, одно от другого:
На строке 46 я написал код, который закроет диспетчер. Я закомментировал его, чтоб никто случайно не сломал себе диспетчер макросов, скачав моё приложение с гитхаба.
На всякий случай, код этой статьи на гитхаб я отправлю в закомментированном виде, чтобы никому случайно потом ничего не сломать.
На 47 строке мы выводим TaskDialog. Будьте осторожны, если в обработчике этого события вызывать TaskDialog, то получите зацикливание (новое событие, новое окно), и вылет Ревита. Я тут избегаю этого с помощью проверки DialogId.
В общем-то, и всё. Примерно таким нехитрым способом можно обрабатывать события в Revit на базовом уровне.
Итоговый закомментированный код на Гитхабе.
Напоминаю, что у меня есть телеграм-канал — буду рад видеть вас там. До новых встреч!