Обновление чертежа при изменении слоя или объекта

Автор Тема: Обновление чертежа при изменении слоя или объекта  (Прочитано 12810 раз)

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

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

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

  • ADN Club
  • Сообщений: 31
  • Карма: 2
Здравствуйте. Не так давно задавал вопрос по поводу обновления чертежа - нужно было выделять объект и подсвечивать его на чертеже. Получил решение используя Editor.UpdateScreen.

Однако выяснил, что данное решение не помогает мне при изменении параметров объекта. Имею следующую проблему:

1. Из диалогового окна WPF задаю новые параметры для объекта/слоя
2. При записи новых параметров, выполняю метод Refresh().

Код - C# [Выбрать]
  1. public static void Refresh(Document document)
  2.         {
  3.             document.Editor.UpdateScreen();
  4.         }

3. Но чертеж не обновляется сразу же после нажатия кнопки изменить "объект". Вижу изменения только при установке фокуса на окно чертежа.

Ниже привожу исходных код метода, обновляющего параметры объекта/слоя:

Код - C# [Выбрать]
  1. public static void ChangeObject(string id, int colorIndex, bool visible, string name, string objectClass,
  2.             double pointX1, double pointX2, double pointY1, double pointY2, double circleRadius, double pointZ)
  3.         {
  4.             doc = Application.DocumentManager.MdiActiveDocument;
  5.             db = doc.Database;
  6.             using (doc.LockDocument())
  7.  
  8.             {
  9.                 using (trans = db.TransactionManager.StartOpenCloseTransaction())
  10.                 {
  11.                     if (objectClass == "Слой")
  12.                     {
  13.                         var lt = trans.GetObject(db.LayerTableId, OpenMode.ForRead) as LayerTable;
  14.                         if (lt != null)
  15.                         {
  16.                             foreach (var objId in lt)
  17.                             {
  18.                                 var ltr = trans.GetObject(objId, OpenMode.ForWrite) as LayerTableRecord;
  19.                                 if (ltr.Id.ToString() == id)
  20.                                 {
  21.                                     ltr.Color = Color.FromColorIndex(ColorMethod.ByAci,
  22.                                             short.Parse(colorIndex.ToString()));
  23.                                     ltr.Name = name;
  24.                                     ltr.IsOff = visible != true;
  25.                                 }
  26.                             }
  27.                         }
  28.                         trans.Commit();
  29.                     }
  30.                     else
  31.                     {
  32.                         PromptSelectionResult getSel = doc.Editor.SelectAll();
  33.                        
  34.                         if (getSel.Status == PromptStatus.OK)
  35.                         {
  36.                             SelectionSet selSet = getSel.Value;
  37.  
  38.                             foreach (SelectedObject selObj in selSet)
  39.                             {
  40.                                 switch (objectClass)
  41.                                 {
  42.                                     case "Точка":
  43.                                         var point = trans.GetObject(selObj.ObjectId, OpenMode.ForWrite) as DBPoint;
  44.                                         if (point != null && point.Id.ToString() == id)
  45.                                         {
  46.                                             //Type entType = ent.GetType();
  47.                                             //switch (entType.Name)
  48.                                             point.Position = new Point3d(pointX1, pointY1, pointZ);
  49.                                             //line = new Line();
  50.                                             //circle = new Circle();
  51.                                         }
  52.                                         break;
  53.                                     case "Линия":
  54.                                         var line = trans.GetObject(selObj.ObjectId, OpenMode.ForWrite) as Line;
  55.                                         if (line != null && line.Id.ToString() == id)
  56.                                         {
  57.                                             line.StartPoint = new Point3d(pointX1, pointY1, pointZ);
  58.                                             line.EndPoint = new Point3d(pointX2, pointY2, pointZ);
  59.                                         }
  60.                                         break;
  61.                                     case "Окружность":
  62.                                         var circle = trans.GetObject(selObj.ObjectId, OpenMode.ForWrite) as Circle;
  63.                                         if (circle != null && circle.Id.ToString() == id)
  64.                                         {
  65.                                             circle.Center = new Point3d(pointX1, pointY1, pointZ);
  66.                                             circle.Radius = circleRadius;
  67.                                         }
  68.                                         break;
  69.                                     default:
  70.                                         MessageBox.Show("Выберите объект, для которого необходимо внести изменения");
  71.                                         return;
  72.                                 }
  73.                             }
  74.                         }
  75.                         trans.Commit();
  76.                     }
  77.                 }
  78.             }
  79.             Refresh(doc);
  80.         }


Код - C# [Выбрать]
  1. string id, int colorIndex, bool visible, string name, string objectClass,
  2.             double pointX1, double pointX2, double pointY1, double pointY2, double circleRadius, double pointZ

Это соответствующий набор значений параметров, которые должны быть установлены для выбранного в диалоговом окне объекта. Чувствую, что решение простое, но, возможно, слишком закопался и не вижу его на поверхности.  Буду благодарен Вам за помощь.

« Последнее редактирование: 15-02-2015, 17:49:06 от Александр Ривилис »

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Радикальный метод:
Код - C# [Выбрать]
  1. document.Editor.Regen();
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN Club
  • Сообщений: 31
  • Карма: 2
В случае, когда меняю параметры линии/точки/окружности - помогло, однако если меняю параметры слоя, например цвет, обновления не происходит. В чем может быть проблема?

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
однако если меняю параметры слоя, например цвет, обновления не происходит.
А должно? Обновление чего должно произойти?
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN Club
  • Сообщений: 31
  • Карма: 2
Я изменяю, к примеру, видимость слоя, свойство IsOff. Соответственно все объекты, относящиеся к слою должны стать невидимыми. И это происходит, но только при фокусировке на окне чертежа.

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Ну попробуй ещё:
Код - C# [Выбрать]
  1. document.Editor.ApplyCurDwgLayerTableChanges();
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN Club
  • Сообщений: 31
  • Карма: 2
Хм, такой метод не предусмотрен, судя по тому, что выдает студия. Видимо версия dll, что использую, не включает его, буду разбираться. Спасибо)

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
В какой версии AutoCAD?
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN Club
  • Сообщений: 31
  • Карма: 2

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
В 2012 такого метода не было. Тогда нужно пользоваться P/Invoke для функции:
Код - C++ [Выбрать]
  1. void acdbApplyCurDwgLayerTableChanges();
Почитай эту тему: http://www.caduser.ru/forum/index.php?PAGE_NAME=message&FID=49&TID=48608&MID=271364#message271364
 
« Последнее редактирование: 15-02-2015, 19:06:02 от Александр Ривилис »
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Где-то так:
Код - C# [Выбрать]
  1. [DllImport("acad.exe",
  2.            EntryPoint = "?acdbApplyCurDwgLayerTableChanges@@YAXXZ",
  3.            CallingConvention = CallingConvention.Cdecl)]
  4. private static extern void acdbApplyCurDwgLayerTableChanges();
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN Club
  • Сообщений: 31
  • Карма: 2
Попробовал данный вариант, проблема осталась: только при фокусировке обновляется чертеж. Проблема актуальна только для слоев.
Своеобразным костылем прикрутил MessageBox, который говорит мне о том, что слой обновлен, и показывает его свойства, т.к. после нажатия ОК происходит фокусировка на чертеже и объекты пропадают.


Отмечено как Решение Даниил 15-02-2015, 20:14:19

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Попробовал данный вариант, проблема осталась: только при фокусировке обновляется чертеж.
Ну тогда для фокусировки ты можешь воспользоваться методом:
Код - C# [Выбрать]
  1. Autodesk.AutoCAD.Internal.Utils.SetFocusToDwgView();
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Кстати, еще и замени строку
Код - C# [Выбрать]
  1. using (trans = db.TransactionManager.StartOpenCloseTransaction())
на
Код - C# [Выбрать]
  1. using (trans = doc.TransactionManager.StartOpenCloseTransaction())
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Я внимательнее посмотрел на твой код и у меня остатки волос стали дыбом.
1) Зачем передавать id в виде строки? Почему не передать нормально ObjectId
2) Зачем передавать objectClass, если эта информация есть в ObjectId?
3) Зачем перебирать все слои чтобы найти слой с известным ObjectId?
4) Зачем перебирать все примитивы чертежа для того чтобы найти примитив с заданным ObjectId?
5) ...
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение