Событие - изменение значения параметра в семействе.

Автор Тема: Событие - изменение значения параметра в семействе.  (Прочитано 14403 раз)

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

Оффлайн enot

  • ADN OPEN
  • *****
  • Сообщений: 525
  • Карма: 2
Пробую сделать подобное , но при запуске ревит выдает ошибку (с кодом выше та же ошибка):




Оффлайн Александр Игнатович

  • Administrator
  • *****
  • Сообщений: 1152
  • Карма: 338
  • Skype: alexandr.ignatovich.itc
Пропустили пространство имен, я так, на самом деле даже не знаю, куда .Net положит класс без определения пространства имен, т.е. в классе должно быть что-то вроде:
Код - C# [Выбрать]
  1. namespace MP.RevitReinforcmentLibrary.RevitApp
  2. {
  3.     public class RevitApplication : IExternalApplication
  4.     {
  5.         public Result OnStartup(UIControlledApplication application)...

В манифесте addin:
Код - XML [Выбрать]
  1. ...
  2.     <Assembly>./MP.RevitReinforcmentLibrary/MP.RevitReinforcmentLibrary.RevitApp.dll</Assembly>
  3.     <FullClassName>MP.RevitReinforcmentLibrary.RevitApp.RevitApplication</FullClassName>
  4. ...
  5.  

Оффлайн enot

  • ADN OPEN
  • *****
  • Сообщений: 525
  • Карма: 2
создать новый updaterId можно так:

Код - C# [Выбрать]
  1. static AddInId appId;
  2.     static UpdaterId updaterId;
  3.     public ParameterUpdater(AddInId id)
  4.     {
  5.        appId = id;
  6.        updaterId = new UpdaterId(appId, new Guid("...."));
  7.     }

каким образом можно получить все updaterId в Ревит? Это требуется чтобы если данный updaterId уже есть, то мы  удаляем его и привязываем к нашему событию
« Последнее редактирование: 01-08-2018, 20:53:29 от enot »

Оффлайн toxanАвтор темы

  • ADN OPEN
  • Сообщений: 8
  • Карма: 0
Да меня тоже данный вопрос очень интересует!

Оффлайн Александр Игнатович

  • Administrator
  • *****
  • Сообщений: 1152
  • Карма: 338
  • Skype: alexandr.ignatovich.itc
Через API получить все апдейтеры я возможности не вижу, можно попробовать распарсить журнал.

Но для Вашего случая больше подходит статический метод:
Код - C# [Выбрать]
  1. UpdaterRegistry.IsUpdaterRegistered(updaterId)

Или
Код - C# [Выбрать]
  1. UpdaterRegistry.IsUpdaterRegistered(updaterId, doc)

Т.е. проверяете, зарегистрирован ли Ваш конкретный апдейтер

Оффлайн toxanАвтор темы

  • ADN OPEN
  • Сообщений: 8
  • Карма: 0
Спасибо добрый человек.

Оффлайн Александр Игнатович

  • Administrator
  • *****
  • Сообщений: 1152
  • Карма: 338
  • Skype: alexandr.ignatovich.itc
Поправочка, можно получить часть информации о всех зарегистрированных апдейтерах, но там довольно немного информации, см. класс UpdaterInfo со свойствами ApplicationName, UpdaterName, IsOptional

Методы:
Код - C# [Выбрать]
  1. UpdaterRegistry.GetRegisteredUpdaterInfos()
и
Код - C# [Выбрать]
  1. UpdaterRegistry.GetRegisteredUpdaterInfos(doc)





Оффлайн enot

  • ADN OPEN
  • *****
  • Сообщений: 525
  • Карма: 2
Тогда смотрите в теме выше.

Во-первых, есть IUpdater - его метод Execute() выполняется когда "транзакция почти завершена", в нем можно получить все добавленные / измененные элементы согласно фильтра, который передается при его регистрации, здесь можно вносить изменения в модель

Во-вторых, событие DocumentChanged, в него уже прилетают все изменения, получаем элементы, анализируем, что-то делаем (но без возможности вносить изменения в модель)

Если нет возможности вносить изменения в модель (изменять например значение параметра элемента), то возможно ли как то в  DocumentChanged использовать метод  Execute() ? или наоборот...



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

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Тогда смотрите в теме выше.

Во-первых, есть IUpdater - его метод Execute() выполняется когда "транзакция почти завершена", в нем можно получить все добавленные / измененные элементы согласно фильтра, который передается при его регистрации, здесь можно вносить изменения в модель

Во-вторых, событие DocumentChanged, в него уже прилетают все изменения, получаем элементы, анализируем, что-то делаем (но без возможности вносить изменения в модель)

Если нет возможности вносить изменения в модель (изменять например значение параметра элемента), то возможно ли как то в  DocumentChanged использовать метод  Execute() ? или наоборот...

Зачем вообще нужен DocumentChanged, если можно обойтись IUpdater'ом?
А вообще - конечно возможно. Вы можете нужную логику работы заложить в отдельном статическом классе и вызывать методы из него, когда требуется. Сложности будут только с контекстом Ревита и транзакцией. Но все решаемо

Оффлайн enot

  • ADN OPEN
  • *****
  • Сообщений: 525
  • Карма: 2
Зачем вообще нужен DocumentChanged, если можно обойтись IUpdater'ом?

Я могу ошибаться, но как я заметил когда я отслеживаю изменение значения параметра через IUpdater' то он реагирует только на изменение , которое произвел пользователь - допустим мы отслеживаем координату Х элемента - IUpdater' реагирует только если вручную вбить координату. А если использовать  DocumentChanged , то он отследит изменение - когда мы перенесли элемент --> координата Х изменилась автоматом --> это изменение отследит DocumentChanged (как раз это и нужно --> чтобы записать значение в другой параметр) , а IUpdater'  нет

Оффлайн Александр Игнатович

  • Administrator
  • *****
  • Сообщений: 1152
  • Карма: 338
  • Skype: alexandr.ignatovich.itc
Нет, это где-то в Вашем коде проблема, или неверный тип изменения, или с фильтром при регистрации. IUpdater-ы использую очень с давних времен и всегда успешно

Оффлайн toxanАвтор темы

  • ADN OPEN
  • Сообщений: 8
  • Карма: 0
А есть ли  метод позволяющий "просмотреть" какой метод был вызван  при нажатии кнопки мыши.

Суть проблемы в чем:
Ведомости можно разделить средствами ревита, но данный метод отсутствует в API.
Вот и возникло желание вытащить метод непосредственно из ревита.
Не дожидаясь его добавления в API.




Оффлайн Александр Игнатович

  • Administrator
  • *****
  • Сообщений: 1152
  • Карма: 338
  • Skype: alexandr.ignatovich.itc
Что происходит в Revit лучше всего описывает его журнал.

Касательно сути вопроса. Вообще Revit-овские .Net-овые библиотеки (RevitAPI.dll, RevitAPIUI.dll и прочие) содержат, как managed, так и unmanaged код и по сути являются достаточно тонким wrapper-ом для вызова функций ядра из самого Revit.

Чисто теоретически, наверное, можно попробовать применить подобный подход, хотя, как мне кажется, для этого надо как минимум иметь заголовочные .h-файлы, либо использовать механизмы pInvoke.

Да, и насколько понимаю, здесь без дизассемблирования не обойтись, что, насколько знаю, противоречит условиям лицензионного соглашения.

Оффлайн dmitrymaslakov

  • ADN OPEN
  • Сообщений: 40
  • Карма: 1
Можно ли указать в правилах фильтра имя пользовательского параметра экземпляра, за изменениями которого нужно следить?