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

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

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

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

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

  • ADN OPEN
  • Сообщений: 8
  • Карма: 0
Добрый день!
Подскажите, можно ли  в фоновом режиме  "увидеть" изменение параметра в определенном семействе? 
Как пример - изменение отметки семейства?


« Последнее редактирование: 31-07-2018, 14:38:10 от Александр Ривилис »

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

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Можно. Для этого нужно использовать IUpdater.
Там при регистрации есть варианты за чем следить - изменением геометрии, изменением параметра или за всеми изменениями.
А уже в обработчике события вы можете проверять, что это нужное вам семейство изменилось

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

  • Administrator
  • *****
  • Сообщений: 1152
  • Карма: 338
  • Skype: alexandr.ignatovich.itc
Александр, лучше не в IUpdater такое разруливать, а в фильтре, который передается при регистрации апдейтра, что-то вроде такого:
Код - C# [Выбрать]
  1. public ElementFilter CreateCableTrayUnionWithConduitSymbolFilter()
  2. {
  3.         var familyNameRule = ParameterFilterRuleFactory.CreateEqualsRule(new ElementId(BuiltInParameter.ALL_MODEL_FAMILY_NAME), CableTrayUnionWithConduitFamilyName, false);
  4.  
  5.         var symbolNameRule = ParameterFilterRuleFactory.CreateEqualsRule(new ElementId(BuiltInParameter.SYMBOL_NAME_PARAM), CableTrayUnionWithConduitFamilySymbolName, false);
  6.  
  7.         var filters = new ElementFilter[]
  8.                 {
  9.                         new ElementIsElementTypeFilter(),
  10.                         new ElementCategoryFilter(BuiltInCategory.OST_CableTrayFitting),
  11.                         new ElementParameterFilter(new [] {familyNameRule, symbolNameRule})
  12.                 };
  13.  
  14.         return new LogicalAndFilter(filters);
  15. }

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

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
а в фильтре, который передается при регистрации апдейтра
Ага, точно. Я просто забыл - под рукой не было кода никакого))

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

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

Т.е., например, 1 апдейтер реагирует на добавление элементов с фильтром по определенным критериям, читаем текущее значение параметра, пишем в extensible storage, второй апдейтер по тому же фильтру реагирует на изменение элемента, в методе Execute сравниваем значение параметра со значением, сохраненным в сторадже и, если они не совпадают, обновляем значение в сторадже и делаем что-то полезное :-)

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

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Кстати, для решения задачи еще потребуется где-то хранить прошлое значение, это может быть Extensible storage или параметр проекта/семейства, возможно невидимый.

Т.е., например, 1 апдейтер реагирует на добавление элементов с фильтром по определенным критериям, читаем текущее значение параметра, пишем в extensible storage, второй апдейтер по тому же фильтру реагирует на изменение элемента, в методе Execute сравниваем значение параметра со значением, сохраненным в сторадже и, если они не совпадают, обновляем значение в сторадже и делаем что-то полезное :-)
Ну мы не знаем, что хочет автор вопроса, поэтому нет смысла и гадать варианты реализации =)
Например, я делал подобную штуку и мне совершенно не важно было прошлое значение - я обрабатывал только текущее (новое). Все зависит от задачи

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

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

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

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

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

  • ADN OPEN
  • Сообщений: 8
  • Карма: 0
Коллеги, голову сломал.
Нужно отследить в семействе обобщенной модели  ЗНАЧЕНИЕ параметра отметки  от уровня. 
Не могу понять с какой стороны подкопаться.
Затык именно в том как получить  значение параметра при его изменении.

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

  • Administrator
  • *****
  • Сообщений: 1152
  • Карма: 338
  • Skype: alexandr.ignatovich.itc
А в чем проблема?

Код - C# [Выбрать]
  1. var value = elem.get_Parameter(BuiltInParameter.INSTANCE_FREE_HOST_OFFSET_PARAM).AsDouble();

При необходимости использовать UnitUtils для преобразования в метры, миллиметры или еще в какие единицы

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

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

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

  • ADN OPEN
  • Сообщений: 8
  • Карма: 0
Статика,  то понятна.
Хотелось бы фоном отслеживать изменение параметра.
От начала работы до закрытия файла.
Т.е. если в семействе изменился параметр - то я тут же увидел что он изменился. Т.е. я  должен получить доступ к событию изменения ЗНАЧЕНИЯ параметра  в фоновом режиме, при каждом его изменении.

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

  • Administrator
  • *****
  • Сообщений: 1152
  • Карма: 338
  • Skype: alexandr.ignatovich.itc
Тогда смотрите в теме выше.

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

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

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

  • ADN OPEN
  • Сообщений: 8
  • Карма: 0
Нужен код который реализует:


Я БЫЛ БЫ ОЧЕНЬ ПРИЗНАТЕЛЕН, ЕСЛИ КТО-ТО ПОМОГ МНЕ С ДАННЫМ КОДОМ. 


Отмечено как Решение toxan 31-07-2018, 15:09:18

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

  • Administrator
  • *****
  • Сообщений: 1152
  • Карма: 338
  • Skype: alexandr.ignatovich.itc
Код - C# [Выбрать]
  1. public class App : IExternalApplication
  2. {
  3.         private readonly ElementId elementId = new ElementId(706288);
  4.  
  5.         public Result OnStartup(UIControlledApplication application)
  6.         {
  7.                 application.ControlledApplication.DocumentChanged += OnDocumentChanged;
  8.  
  9.                 return Result.Succeeded;
  10.         }
  11.  
  12.         public Result OnShutdown(UIControlledApplication application)
  13.         {
  14.                 application.ControlledApplication.DocumentChanged -= OnDocumentChanged;
  15.  
  16.                 return Result.Succeeded;
  17.         }
  18.  
  19.         private void OnDocumentChanged(object sender, DocumentChangedEventArgs e)
  20.         {
  21.                 if (!e.GetModifiedElementIds().Contains(elementId))
  22.                         return;
  23.  
  24.                 var document = e.GetDocument();
  25.  
  26.                 var element = document.GetElement(elementId);
  27.  
  28.                 TaskDialog.Show("dev", element.get_Parameter(BuiltInParameter.ALL_MODEL_INSTANCE_COMMENTS).AsString());
  29.         }
  30. }