Переключение на другой лист в другом открытом документе

Автор Тема: Переключение на другой лист в другом открытом документе  (Прочитано 22183 раз)

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

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

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

  • ADN Club
  • **
  • Сообщений: 78
  • Карма: 1
  • c# autocad
  • Skype: johnj255work
Добрый день! Открыто несколько документов, нужно сделать лист одного из документов активным.
Использую для этого следующий код:
Код - C# [Выбрать]
  1. if (DocumentActivate(doc_name)) {
  2.     LayoutManager.Current.CurrentLayout = layout_name;
  3. }
  4.  
где
Код - C# [Выбрать]
  1. public bool DocumentActivate(string doc_name) {
  2.             try {
  3.                 if (DocumentManager.MdiActiveDocument.Name == doc_name) return true;
  4.                 var document = DocumentManager.Cast<Document>().First(doc => doc.Name == doc_name);
  5.                 if (document == null) return false;
  6.                 using (DocumentManager.MdiActiveDocument.LockDocument()) {
  7.                     DocumentManager.MdiActiveDocument = document;
  8.                 }
  9.                 return true;
  10.             } catch (Exception exception) {
  11.                 MessageBox.Show(exception.Message);
  12.             }
  13.             return false;
  14.         }
  15.  
c# autocad 2012

На строке LayoutManager.Current.CurrentLayout = layout_name; выскакивает ошибка: eSetFailed. Подозреваю, что связана она с тем, что текущий документ ещё не стал текущим. Если вписать перед этой строкой return (прервать выполнение метода), то автокад ждёт бесконечно долго. Если закрыть окно моего плагина - документ в автокаде тут же переключится на указанный ранее в программе. Как сделать, что бы документ переключался сразу, а моя программа получила управление для продолжения действий по завершению переключения?
Я уже пробовал и DoEvents() и Editor.Update и даже Editor.Regenerate и AcApplication.UpdateScreen(). Ничего не помогло что-то...

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

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

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

  • ADN Club
  • **
  • Сообщений: 78
  • Карма: 1
  • c# autocad
  • Skype: johnj255work
командой запускается окно (через ShowDialog, хотя пробовал уже и Show просто), на окне нажимается кнопка, которая выполняет этот код.
У команды указан флаг CommandFlags.Session

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

  • Administrator
  • *****
  • Сообщений: 13918
  • Карма: 1793
  • Рыцарь ObjectARX
  • Skype: rivilis
Попробуй перед выполнением DocumentActivate вызвать
Код - C# [Выбрать]
  1. DocumentManager.DocumentActivationEnabled = true;
Я не могу понять зачем вот это у тебя в коде:
Код - C# [Выбрать]
  1.                 using (DocumentManager.MdiActiveDocument.LockDocument()) {
  2.                     DocumentManager.MdiActiveDocument = document;
  3.                 }
Зачем блокировать старый активный документ при переключении в новый?
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN Club
  • **
  • Сообщений: 78
  • Карма: 1
  • c# autocad
  • Skype: johnj255work
чуть подправил метод  DocumentActivate - исправил неточность с return true и false.
Блокировка старого документа осталась от экспериментов, пока я не узнал про CommandFlags.Session
Если это не требуется, я сейчас попробую убрать лишнее действие.
Теперь метод стал таким:
Код - C# [Выбрать]
  1.         public bool DocumentActivate(string doc_name) {
  2.             try {
  3.                 if (DocumentManager.MdiActiveDocument.Name == doc_name) return true;
  4.                 DocumentManager.DocumentActivationEnabled = true;
  5.                 var document = DocumentManager.Cast<Document>().First(doc => doc.Name == doc_name);
  6.                 if (document == null) return false;
  7.                 DocumentManager.MdiActiveDocument = document;
  8.                 return true;
  9.             } catch (Exception exception) {
  10.                 MessageBox.Show(exception.Message);
  11.             }
  12.             return false;
  13.         }
  14.  

Но реакция не изменилась - та же ошибка в том же месте.

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

  • ADN Club
  • **
  • Сообщений: 78
  • Карма: 1
  • c# autocad
  • Skype: johnj255work
Сейчас перечитал ваш совет: убрал DocumentManager.DocumentActivationEnabled = true; из метода и перенёс перед его вызовом. В результате ошибка eInvalidContext на этой строке. Это свойство перед выполнением этой строки уже имеет значение true, возможно поэтому выдаётся ошибка?

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

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

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

  • Administrator
  • *****
  • Сообщений: 13918
  • Карма: 1793
  • Рыцарь ObjectARX
  • Skype: rivilis
Сейчас перечитал ваш совет: убрал DocumentManager.DocumentActivationEnabled = true; из метода и перенёс перед его вызовом. В результате ошибка eInvalidContext на этой строке
Нужно сначала проверить состояние DocumentActivationEnabled, и если оно false переключить на true.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

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

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

  • ADN Club
  • **
  • Сообщений: 78
  • Карма: 1
  • c# autocad
  • Skype: johnj255work
всегда использовал такой способ: (new MyForm()).ShowDialog();
Сейчас попробую сделать как вы сказали.
Итог: в случае ShowModalDialog DocumentActivationEnabled была false.
Ошибка eSetFailed осталась.

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

  • Administrator
  • *****
  • Сообщений: 13918
  • Карма: 1793
  • Рыцарь ObjectARX
  • Skype: rivilis
всегда использовал такой способ: (new MyForm()).ShowDialog();
Неправильно. В AutoCAD нужно использовать Application.ShowModalDialog.
Ошибка eSetFailed осталась.
Вполне возможно, что в этом контексте нельзя переключится на другой лист. А зачем тебе это нужно?
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN Club
  • **
  • Сообщений: 78
  • Карма: 1
  • c# autocad
  • Skype: johnj255work
нужно использовать Application.ShowModalDialog
Спасибо! Буду теперь использовать такой подход.

Возможно как-то можно с помощью Interop?
Моя форма содержит список листов всех открытых документов, нужно что бы выбранный лист экспортировался в модель. В рамках одного документа программа работает, а вот при двух уже не может переключиться на другой документ как мне необходимо.
Экспорт работает только для активного листа и выдаёт ошибку, если лист экспортируется до его активации.

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

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

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

  • ADN Club
  • **
  • Сообщений: 78
  • Карма: 1
  • c# autocad
  • Skype: johnj255work
а как отследить, что документ уже поменялся и можно снова запускаться?

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

  • Administrator
  • *****
  • Сообщений: 13918
  • Карма: 1793
  • Рыцарь ObjectARX
  • Skype: rivilis
а как отследить, что документ уже поменялся и можно снова запускаться?
Вообще-то по событию DocumentCollection.DocumentActivated
Давай попробуем еще одну вещь:
1) После вызова DocumentActivate() переключи HostApplicationServices.WorkingDatabase на новую базу
2) Блокируй новую базу
3) Вызывай LayoutManager.Current.CurrentLayout = layout_name;
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение