Событие DBObject.Modified и изменение словаря объекта.

Автор Тема: Событие DBObject.Modified и изменение словаря объекта.  (Прочитано 7213 раз)

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

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

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Сегодня, наконец-то, (тадам  :D) нашел ошибку в своей программе, которую долго не мог "пофиксить". Ошибка оказалась в моем неправильном представлении логики работы события DBObject.Modified при изменении словаря объекта - ExtensionDictionary. Я, почему-то, наивно предполагал, что если мы редактируем словарь объекта, то это вызовет событие модификации объекта. На самом деле, это событие вызывается только если мы создаем или удаляем словарь объекта, т.к. сам словарь, по сути, отдельный объект базы данных чертежа.
Подумав, пришел к выводу, что самое простое и надежное, что можно сделать - добавить в код моего метода модификации словаря что-то такое, что вызывало бы модификацию его владельца. Просто открытие объекта-владельца на запись событие модификации не вызывает.
Что бы такое добавить, чтобы это работало с любым объектом типа DBObject?

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Что бы такое добавить, чтобы это работало с любым объектом типа DBObject?
Код - C# [Выбрать]
  1. DBObject.Erase(true);
  2. DBObject.Erase(false);
Впрочем может быть побочный эффект.
Еще вариант - изменение/восстановление DBObject.XData.
Пока других идей не возникло.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Да, пожалуй, это чуть ли не единственный вариант, если рассматривать DBObject. Но что-то я опасаюсь удалять объекты, т.к. в основном имею дело с объектами Civil и неясно, что станет с динамическими связями при удалении объекта. Буду думать, спасибо!

Оффлайн Привалов Дмитрий

  • ADN Club
  • *****
  • Сообщений: 546
  • Карма: 119
Буду думать, спасибо!
может проще логику поменять?
отказаться от отслеживания события изменения самого объекта
отслеживать изменения словаря, и в данном событии вызывать нужный метод для его владельца

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Просто открытие объекта-владельца на запись событие модификации не вызывает.
Что бы такое добавить, чтобы это работало с любым объектом типа DBObject?

Я вот проверил такой код:

Код - C# [Выбрать]
  1. using System;
  2. using Autodesk.AutoCAD.Runtime;
  3. using Autodesk.AutoCAD.ApplicationServices;
  4. using Autodesk.AutoCAD.DatabaseServices;
  5. using Autodesk.AutoCAD.Geometry;
  6. using Autodesk.AutoCAD.EditorInput;
  7.  
  8. // This line is not mandatory, but improves loading performances
  9. [assembly: CommandClass(typeof(TestModify.MyCommands))]
  10.  
  11. namespace TestModify
  12. {
  13.   public class MyCommands
  14.   {
  15.     [CommandMethod("TestMod", CommandFlags.Modal)]
  16.     public void MyCommand()
  17.     {
  18.       Document doc = Application.DocumentManager.MdiActiveDocument;
  19.       if (doc == null) return;
  20.       Editor ed = doc.Editor;
  21.       PromptEntityResult rs = ed.GetEntity("\nВыберите примитив");
  22.       if (rs.Status != PromptStatus.OK) return;
  23.       using (DBObject obj = rs.ObjectId.Open(OpenMode.ForWrite))
  24.       {
  25.         obj.DowngradeToNotify(true);
  26.       }
  27.     }
  28.   }
  29. }

Событие модификации возникает (во всяком случае в ObjectARX):



Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Отмечено как Решение Дмитрий Загорулькин 11-03-2016, 09:57:59

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
А вот так для DBObject:

Код - C# [Выбрать]
  1. [CommandMethod("TestModObj", CommandFlags.Modal)]
  2. public void MyCommandObj()
  3. {
  4.   Document doc = Application.DocumentManager.MdiActiveDocument;
  5.   if (doc == null) return;
  6.   Editor ed = doc.Editor;
  7.   PromptResult rs = ed.GetString("\nУкажите метку объекта");
  8.   if (rs.Status != PromptStatus.OK) return;
  9.   Handle h = new Handle(Convert.ToInt32(rs.StringResult,16));
  10.   ObjectId id;
  11.   if (doc.Database.TryGetObjectId(h, out id))
  12.   {
  13.     using (DBObject obj = id.Open(OpenMode.ForWrite))
  14.     {
  15.       obj.DowngradeToNotify(true);
  16.     }
  17.   }
  18. }

Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Странно, почему-то пропустил оповещение об ответах...
Я, в итоге, пошел по пути отслеживания изменений словаря, как предложил Привалов Дмитрий. Там были некоторые сложности из-за того, что словарь у объекта может быть, может отсутствовать, может быть удален и заново создан и т.п. Но это, в принципе, оказалось решаемо. Сейчас проверю Ваш метод.
P.S. Хотя нет, не смогу проверить. У меня в метод записи словаря объект передается открытым на запись, а метод DowngradeToNotify, как я понимаю, будет изменять это состояние. Я опасаюсь, что это может порушить работу в каких-то моих приложениях.