ObjectOverrule.Close

Автор Тема: ObjectOverrule.Close  (Прочитано 14501 раз)

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

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

  • ADN OPEN
  • ****
  • Сообщений: 411
  • Карма: 9
ObjectOverrule.Close
« : 03-02-2019, 15:59:55 »
Добрый день!

почитал про этот метод ObjectOverrule.Close()
но не могу понять как с ним работать. как связать изменение условной полилинии с классом унаследовавшим ObjectOverrule?
как должен вызываться ObjectOverrule.Close() при изменении этой полилинии?

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: ObjectOverrule.Close
« Ответ #1 : 03-02-2019, 16:33:27 »
simson43,
Зачем?
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • ****
  • Сообщений: 411
  • Карма: 9
Re: ObjectOverrule.Close
« Ответ #2 : 03-02-2019, 16:37:28 »
нужно при изменении объекта изменить его XData и другой объект связанный с измененным

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

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Re: ObjectOverrule.Close
« Ответ #3 : 03-02-2019, 16:41:38 »
Overrule это такой механизм в автокаде, который похож на подписку на события. Когда вы "подпишитесь" на ObjectOverrule, то будете иметь возможность переопределять поведение метода Close() для объекта. Но ни в коем случае не нужно его вызывать! Он сам вызывается, когда объект закрывается при модификации.
По сути, подпись на событие ObjectModified очень схожа с обработкой метода ObjectOverrule.Close()

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

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Re: ObjectOverrule.Close
« Ответ #4 : 03-02-2019, 16:46:33 »
нужно при изменении объекта изменить его XData и другой объект связанный с измененным
Вот пример:
Код - C# [Выбрать]
  1. // ReSharper disable InconsistentNaming
  2.  
  3. namespace mpESKD.Functions.mpBreakLine.Overrules
  4. {
  5.     using System.Diagnostics;
  6.     using Autodesk.AutoCAD.DatabaseServices;
  7.     using Autodesk.AutoCAD.Runtime;
  8.     using ModPlusAPI.Windows;
  9.     using Base.Helpers;
  10.     using Base;
  11.  
  12.     public class BreakLineObjectOverrule : ObjectOverrule
  13.     {
  14.         protected static BreakLineObjectOverrule _breakLineObjectOverrule;
  15.  
  16.         public static BreakLineObjectOverrule Instance()
  17.         {
  18.             if (_breakLineObjectOverrule != null) return _breakLineObjectOverrule;
  19.             _breakLineObjectOverrule = new BreakLineObjectOverrule();
  20.             // Фильтр "отлова" примитива по расширенным данным. Работает лучше, чем проверка вручную!
  21.             _breakLineObjectOverrule.SetXDataFilter(BreakLineDescriptor.Instance.Name);
  22.             return _breakLineObjectOverrule;
  23.         }
  24.  
  25.         public override void Close(DBObject dbObject)
  26.         {
  27.             Debug.Print(dbObject?.GetRXClass().Name);
  28.             if (IsApplicable(dbObject))
  29.             {
  30.                 try
  31.                 {
  32.                     if (AcadHelpers.Document != null)
  33.                         if (dbObject != null && dbObject.IsNewObject & dbObject.Database == AcadHelpers.Database ||
  34.                             dbObject != null && dbObject.IsUndoing & dbObject.IsModifiedXData)
  35.                         {
  36.                             var breakLine = EntityReaderFactory.Instance.GetFromEntity<BreakLine>((Entity)dbObject);
  37.                             if (breakLine != null)
  38.                             {
  39.                                 breakLine.UpdateEntities();
  40.                                 breakLine.GetBlockTableRecordForUndo((BlockReference)dbObject).UpdateAnonymousBlocks();
  41.                             }
  42.                         }
  43.                 }
  44.                 catch (Exception exception)
  45.                 {
  46.                     ExceptionBox.Show(exception);
  47.                 }
  48.             }
  49.             base.Close(dbObject);
  50.         }
  51.  
  52.         public override bool IsApplicable(RXObject overruledSubject)
  53.         {
  54.             return ExtendedDataHelpers.IsApplicable(overruledSubject, BreakLineDescriptor.Instance.Name, true);
  55.         }
  56.     }
  57. }
Подписка:
Код - C# [Выбрать]
  1. /// <inheritdoc />
  2. public void Initialize()
  3. {
  4.     Overrule.AddOverrule(RXObject.GetClass(typeof(BlockReference)), BreakLineObjectOverrule.Instance(), true);
  5. }
  6.  
  7. /// <inheritdoc />
  8. public void Terminate()
  9. {
  10.     Overrule.RemoveOverrule(RXObject.GetClass(typeof(BlockReference)), BreakLineObjectOverrule.Instance());
  11. }

А вот тут можно найти много примеров с описаниями

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

  • ADN OPEN
  • ****
  • Сообщений: 411
  • Карма: 9
Re: ObjectOverrule.Close
« Ответ #5 : 03-02-2019, 17:07:30 »
вот "подписку" я как раз и искал.
спасибо! буду пробовать!

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

  • ADN OPEN
  • ****
  • Сообщений: 411
  • Карма: 9
Re: ObjectOverrule.Close
« Ответ #6 : 03-02-2019, 17:48:15 »
_breakLineObjectOverrule.SetXDataFilter(BreakLineDescriptor.Instance.Name);

это значит что Close() вызовется только для объектов с этим приложением в xdata?

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

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Re: ObjectOverrule.Close
« Ответ #7 : 03-02-2019, 17:58:36 »
это значит что Close() вызовется только для объектов с этим приложением в xdata?
Это значит, что блоки дополнительно фильтруются по наличию XData с AppName равным тому, что у меня записано в переменной BreakLineDescriptor.Instance.Name

Лучше смотрите примеры, на которые я вам ссылку дал

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

  • ADN OPEN
  • ****
  • Сообщений: 411
  • Карма: 9
Re: ObjectOverrule.Close
« Ответ #8 : 03-02-2019, 18:39:53 »
другие объекты лучше обрабатывать/изменять/создавать не в ObjectOverrule.Close? или можно тут же?

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

  • ADN OPEN
  • ****
  • Сообщений: 411
  • Карма: 9
Re: ObjectOverrule.Close
« Ответ #9 : 03-02-2019, 21:48:28 »
видимо можно..

после создания объекта еще раз возникает isModified
как его отфильтровать?

у меня вот так
Код - C# [Выбрать]
  1. dbObject.IsModified && !dbObject.IsNewObject && dbObject.IsWriteEnabled
« Последнее редактирование: 05-02-2019, 12:12:41 от simson43 »

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

  • ADN OPEN
  • ****
  • Сообщений: 411
  • Карма: 9
Re: ObjectOverrule.Close
« Ответ #10 : 04-02-2019, 10:12:24 »
возникла такая же проблема http://adn-cis.org/forum/index.php?topic=7813.msg26217#msg26217
ошибка при открытии транзакции.

UPD:
решилось заменой транзакции на Open
(причину б узнать почему на транзакции падает)
« Последнее редактирование: 04-02-2019, 13:18:35 от simson43 »

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: ObjectOverrule.Close
« Ответ #11 : 04-02-2019, 14:01:14 »
причину б узнать почему на транзакции падает
Потому что гладиолус! :)
Если серьёзно - то 100% причину вряд ли кто-то назовёт. Разве что Александр Наумович знает что-то об этом.
Просто надо взять себе за правило - в "продвинутых" случаях использовать транзакцию не стоит: в обработчиках событий с объектами БД чертежа, в методах любых Overrule и т.п.

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

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Re: ObjectOverrule.Close
« Ответ #12 : 04-02-2019, 14:03:22 »
в "продвинутых" случаях использовать транзакцию не стоит
Иногда прокатывает OpenCloseTransaction, что по сути примерно тоже самое. Но в случае с overrule - только методом проб ошибок можно выявить рабочий вариант)

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: ObjectOverrule.Close
« Ответ #13 : 04-02-2019, 14:17:55 »
Иногда прокатывает OpenCloseTransaction, что по сути примерно тоже самое.
Если имеется в виду, что OpenCloseTransaction - это примерно то же самое, что и транзакция, то это не так. Это её эмуляция с помощью спрятанных внутри вызовов Open и Close. Может облегчить жизнь при работе с несколькими одновременно открываемыми объектами. Но иногда из-за того, что объекты долго остаются открытыми (до самого вызова Commit) могут возникнуть ошибки. А по сути - это то же самое, что и использование Open-Close, но с интерфейсом транзакции.

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

  • ADN OPEN
  • ****
  • Сообщений: 411
  • Карма: 9
Re: ObjectOverrule.Close
« Ответ #14 : 04-02-2019, 14:25:23 »
Так незаметно повысился до статуса продвинутый) приятно
Да после теста с Open, заменил все на OpenCloseTransaction-работает!

Полезное замечение. Спасибо!
Просто надо взять себе за правило - в "продвинутых" случаях использовать транзакцию не стоит: в обработчиках событий с объектами БД чертежа, в методах любых Overrule и т.п.
А можно "и т.п." развернуть?