Сообщество программистов Autodesk в СНГ

ADN Club => AutoCAD .NET API => Тема начата: Дмитрий Загорулькин от 02-03-2016, 18:01:02

Название: Событие DBObject.Modified и изменение словаря объекта.
Отправлено: Дмитрий Загорулькин от 02-03-2016, 18:01:02
Сегодня, наконец-то, (тадам  :D) нашел ошибку в своей программе, которую долго не мог "пофиксить". Ошибка оказалась в моем неправильном представлении логики работы события DBObject.Modified при изменении словаря объекта - ExtensionDictionary. Я, почему-то, наивно предполагал, что если мы редактируем словарь объекта, то это вызовет событие модификации объекта. На самом деле, это событие вызывается только если мы создаем или удаляем словарь объекта, т.к. сам словарь, по сути, отдельный объект базы данных чертежа.
Подумав, пришел к выводу, что самое простое и надежное, что можно сделать - добавить в код моего метода модификации словаря что-то такое, что вызывало бы модификацию его владельца. Просто открытие объекта-владельца на запись событие модификации не вызывает.
Что бы такое добавить, чтобы это работало с любым объектом типа DBObject?
Название: Re: Событие DBObject.Modified и изменение словаря объекта.
Отправлено: Александр Ривилис от 02-03-2016, 18:37:46
Что бы такое добавить, чтобы это работало с любым объектом типа DBObject?
Код - C# [Выбрать]
  1. DBObject.Erase(true);
  2. DBObject.Erase(false);
Впрочем может быть побочный эффект.
Еще вариант - изменение/восстановление DBObject.XData.
Пока других идей не возникло.
Название: Re: Событие DBObject.Modified и изменение словаря объекта.
Отправлено: Дмитрий Загорулькин от 03-03-2016, 15:29:23
Да, пожалуй, это чуть ли не единственный вариант, если рассматривать DBObject. Но что-то я опасаюсь удалять объекты, т.к. в основном имею дело с объектами Civil и неясно, что станет с динамическими связями при удалении объекта. Буду думать, спасибо!
Название: Re: Событие DBObject.Modified и изменение словаря объекта.
Отправлено: Привалов Дмитрий от 03-03-2016, 15:42:23
Буду думать, спасибо!
может проще логику поменять?
отказаться от отслеживания события изменения самого объекта
отслеживать изменения словаря, и в данном событии вызывать нужный метод для его владельца
Название: Re: Событие DBObject.Modified и изменение словаря объекта.
Отправлено: Александр Ривилис от 04-03-2016, 02:41:59
Просто открытие объекта-владельца на запись событие модификации не вызывает.
Что бы такое добавить, чтобы это работало с любым объектом типа 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):



Название: Re: Событие DBObject.Modified и изменение словаря объекта.
Отправлено: Александр Ривилис от 04-03-2016, 02:55:44
А вот так для 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. }

Название: Re: Событие DBObject.Modified и изменение словаря объекта.
Отправлено: Дмитрий Загорулькин от 05-03-2016, 19:11:22
Странно, почему-то пропустил оповещение об ответах...
Я, в итоге, пошел по пути отслеживания изменений словаря, как предложил Привалов Дмитрий. Там были некоторые сложности из-за того, что словарь у объекта может быть, может отсутствовать, может быть удален и заново создан и т.п. Но это, в принципе, оказалось решаемо. Сейчас проверю Ваш метод.
P.S. Хотя нет, не смогу проверить. У меня в метод записи словаря объект передается открытым на запись, а метод DowngradeToNotify, как я понимаю, будет изменять это состояние. Я опасаюсь, что это может порушить работу в каких-то моих приложениях.