ADN Club > AutoCAD .NET API
Обработка объекта (примитива) по событию его модификации.
(1/1)
Дмитрий Загорулькин:
Добрый день!
Есть необходимость пост-модификации объекта. То есть, пользователь редактирует объект, по окончании этого определяются его свойства. Проводится анализ. Если что-то не устраивает - объект автоматически корректируется.
Реализовал это так:
- подписался на событие модификации объекта базы данных (Autodesk.AutoCAD.DatabaseServices.Database.ObjectModified);
- обработчик события проверяет тип объекта и его характеристики, определяет необходимость пост-модификации;
- если объект нужно дообработать, вызываю его метод UpgradeOpen() и провожу необходимые изменения (без запуска дополнительной транзакции, т.к., как я понимаю, при модификации объекта она уже запущена системой).
Это работает как надо, но есть смущающие моменты:
- если отменять действия вызовом стандартной команды UNDO, то возникает исключение из-за того, что "eWasOpenedForUndo".
- один раз было предупреждение "eWasOpenedForModify", почему - понять не успел, повторить не смог.
Защита от этого с помощью try-catch помогает, но может есть более правильный подход для таких действий с объектами?
Александр Ривилис:
Это одно из наиболее тонких мест в ObjectARX / AutoCAD .NET API. В двух словах тот вариант, который ты реализовал некорректный. Фактически ты повторно возбуждаешь событие модификации объекта из обработчика модификации объекта, неявно приводя к рекурсии.
Идеального варианта решения нет. Один из более корректных вариантов- запоминать в Database.ObjectModified id объекта, который нужно будет модифицировать, а реально модифицировать его в событии DocumentLockModeWillChange.
xSAKABSx:
ну либо отписыватся перед отрытием на редактирование,
а после закрытия транзакции опять подписатса !
это Имхо не более надо пробывать
Дмитрий Загорулькин:
--- Цитата: Александр Ривилис от 04-12-2013, 15:27:27 ---Это одно из наиболее тонких мест в ObjectARX / AutoCAD .NET API. В двух словах тот вариант, который ты реализовал некорректный. Фактически ты повторно возбуждаешь событие модификации объекта из обработчика модификации объекта, неявно приводя к рекурсии.
Идеального варианта решения нет. Один из более корректных вариантов- запоминать в Database.ObjectModified id объекта, который нужно будет модифицировать, а реально модифицировать его в событии DocumentLockModeWillChange.
--- Конец цитаты ---
Если верить отладчику, то рекурсии не происходит. Была такая проблема, когда я запускал транзакцию в обработчике, Вы мне тогда на другом ресурсе подсказали, что я в рекурсию увожу этим. А если транзакцию не запускать, то повторного события модификации не происходит. Может быть, событие связано с запуском транзакции?
И задержек во времени при выполнении модификации нет никаких когда автокорректировка срабатывает.
Пока, наверное, оставлю так и понаблюдаю. Если будут проблемы - попробую тот вариант, что Вы предложили.
Александр Ривилис:
--- Цитата: Загорулькин Дмитрий от 04-12-2013, 15:09:24 ---- один раз было предупреждение "eWasOpenedForModify", почему - понять не успел, повторить не смог.
--- Конец цитаты ---
Наверное ты имел в виду eWasOpenForNotify
--- Цитата: xSAKABSx от 04-12-2013, 15:41:34 ---ну либо отписыватся перед отрытием на редактирование,
а после закрытия транзакции опять подписатса !
это Имхо не более надо пробывать
--- Конец цитаты ---
Это не поможет.
Навигация
Перейти к полной версии