Скрыть текст "До" при использовании InplaceTextEditor

Автор Тема: Скрыть текст "До" при использовании InplaceTextEditor  (Прочитано 5266 раз)

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

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

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

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Всем привет. Накидал тут тестовый проектик с использованием InplaceTextEditor в определенных условиях - редактирование однострочного текста, входящего в блок:
Код - C# [Выбрать]
  1. using Autodesk.AutoCAD.ApplicationServices;
  2. using Autodesk.AutoCAD.DatabaseServices;
  3. using Autodesk.AutoCAD.EditorInput;
  4. using Autodesk.AutoCAD.Geometry;
  5. using Autodesk.AutoCAD.Runtime;
  6.  
  7. namespace AutocadInplaceTextEditor
  8. {
  9.     public class TestEdit
  10.     {
  11.         [CommandMethod("TestEditor")]
  12.         public void Test()
  13.         {
  14.             Document doc = Application.DocumentManager.MdiActiveDocument;
  15.             Editor ed = doc.Editor;
  16.            
  17.             PromptEntityOptions peo = new PromptEntityOptions("\nSelect DBText:");
  18.             peo.SetRejectMessage("\nNooo!");
  19.             peo.AddAllowedClass(typeof(BlockReference), true);
  20.             var result = ed.GetEntity(peo);
  21.             if (result.Status == PromptStatus.OK)
  22.             {
  23.                 using (Transaction tr = doc.TransactionManager.StartTransaction())
  24.                 {
  25.                     var selectedBlock = (BlockReference) tr.GetObject(result.ObjectId, OpenMode.ForWrite);
  26.                     var displMat = Matrix3d.Displacement(selectedBlock.Position - Point3d.Origin);
  27.                     var btr = (BlockTableRecord) tr.GetObject(selectedBlock.BlockTableRecord, OpenMode.ForWrite);
  28.                     foreach (ObjectId objectId in btr)
  29.                     {
  30.                         var ent = tr.GetObject(objectId, OpenMode.ForWrite);
  31.                         if (ent is DBText text)
  32.                         {
  33.                             text.TransformBy(displMat);
  34.                             ObjectId[] ids = new ObjectId[0];
  35.                             InplaceTextEditor.Invoke(text, ref ids);
  36.                             if (text.IsModified)
  37.                             {
  38.                                 //
  39.                             }
  40.                             text.TransformBy(displMat.Inverse());
  41.                             ed.Regen();
  42.                         }
  43.                     }
  44.                    
  45.                     tr.Commit();
  46.                 }
  47.             }
  48.         }
  49.     }
  50. }
При таких условиях при редактировании текста я вижу новый текст и старый:



Есть ли способ избежать отображение текста "ДО"? Мне особо это не помешает, но хотелось бы чтобы было чистенько

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

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Один из вариантов (плохой правда вариант) - скрыть весь BlockReference на момент редактирования текста:
Код - C# [Выбрать]
  1. if (ent is DBText text)
  2. {
  3.     selectedBlock.Visible = false;
  4.     text.TransformBy(displMat);
  5.     ObjectId[] ids = new ObjectId[0];
  6.     InplaceTextEditor.Invoke(text, ref ids);
  7.     if (text.IsModified)
  8.     {
  9.         //
  10.     }
  11.     text.TransformBy(displMat.Inverse());
  12.     selectedBlock.Visible = true;
  13.     ed.Regen();
  14. }
Ну это плохой вариант, так как весь блок не видно в момент редактирования текста

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

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
На пару с Вильдаром нашли вариант рабочий:
Код - C# [Выбрать]
  1. if (ent is DBText text)
  2. {
  3.     text.Visible = false;
  4.     ed.Regen();
  5.     text.TransformBy(displMat);
  6.     ObjectId[] ids = new ObjectId[0];
  7.     InplaceTextEditor.Invoke(text, ref ids);
  8.     if (text.IsModified)
  9.     {
  10.         //
  11.     }
  12.     text.TransformBy(displMat.Inverse());
  13.     text.Visible = true;
  14.     ed.Regen();
  15. }
Единственное, что смущает - частое использование ed.Regen(); Не вызовет ли это "тормоза" когда объектов в модели будет очень много?
Пока не помечаю как ответ

Оффлайн Вильдар

  • ADN Club
  • ****
  • Сообщений: 405
  • Карма: 77
  • Skype: vildar82
Из трех вариантов, я бы выбрал первый, когда видно серый исходный текст на заднем плане - это больше на фичу похоже.

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Единственное, что смущает - частое использование ed.Regen(); Не вызовет ли это "тормоза" когда объектов в модели будет очень много?
Вызовет. Зависит от чертежа, конечно.
RecordGraphicsModified пробовали? FlushGraphics?
Или начальное содержимое текста сохранять в переменной, очищать его и потом уже пустым передавать в InplaceTextEditor. Если text.IsModified не выполняется - восстановить исходное значение.

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

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
RecordGraphicsModified пробовали? FlushGraphics?
Пробовал - нет эффекта. Только ed.Regen();
Или начальное содержимое текста сохранять в переменной, очищать его и потом уже пустым передавать в InplaceTextEditor. Если text.IsModified не выполняется - восстановить исходное значение
Тогда в редактор передастся текст с пустым значением =) Тоже не вариант
Вызовет. Зависит от чертежа, конечно.
Вот это и грустно

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Если ты редактируешь текст внутри блока, то помочь может или Editor.Regen() или RecordGraphicsModified плюс QueueForGraphicsFlush, но (!!!) для всех вставок этого блока и не внутри транзакции.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
или RecordGraphicsModified плюс QueueForGraphicsFlush
Попробовал - не помогло. НО
но (!!!) для всех вставок этого блока и не внутри транзакции
Я не понял - как я это могу сделать НЕ внутри транзакции?

Отмечено как Решение Александр Пекшев aka Modis 12-03-2018, 19:15:55

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

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Все! Получилось! В одной транзакции, кстати. Вся проблема у меня был в том, что я метод RecordGraphicsModified вызывал с аргументом false, а надо было true (кстати, в чем разница?)

Извините, вам запрещён просмотр содержимого спойлеров.

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

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Что самое интересное - работает и так:
Код - C# [Выбрать]
  1. selectedBlock.RecordGraphicsModified(true);
  2. doc.TransactionManager.FlushGraphics();
и так:
Код - C# [Выбрать]
  1. selectedBlock.RecordGraphicsModified(true);
  2. db.TransactionManager.QueueForGraphicsFlush();
Лично для меня не ясно в чем разница этих методов

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Вся проблема у меня был в том, что я метод RecordGraphicsModified вызывал с аргументом false, а надо было true (кстати, в чем разница?)
Разница в том, что при false ты отмечал, что графика не менялась, а при true отмечаешь, что она изменилась. Соответственно TransactionManager.QueueForGraphicsFlush() делать было нечего - чего перерисовывать если графика не меняется.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Что самое интересное - работает и так:
Код - C# [Выбрать]
  1. selectedBlock.RecordGraphicsModified(true);
  2. doc.TransactionManager.FlushGraphics();
и так:
Код - C# [Выбрать]
  1. selectedBlock.RecordGraphicsModified(true);
  2. db.TransactionManager.QueueForGraphicsFlush();
Лично для меня не ясно в чем разница этих методов
Лучше использовать doc.TransactionManager.FlushGraphics(); - используется менеджер транзакций документа, а не базы данных.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Вся проблема у меня был в том, что я метод RecordGraphicsModified вызывал с аргументом false, а надо было true (кстати, в чем разница?)
Разница в том, что при false ты отмечал, что графика не менялась, а при true отмечаешь, что она изменилась. Соответственно TransactionManager.QueueForGraphicsFlush() делать было нечего - чего перерисовывать если графика не меняется.
Тогда логичный вопрос - в каких случаях нужно false? Зачем это?

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

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

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Тогда логичный вопрос - в каких случаях нужно false? Зачем это?
Пример. Ты поменял расширенные данные примитива, которые не влияют на его отображение, но сам примитив поменялся. Чтобы не происходило перерисовки - вызывай RecordGraphicsModified(false)
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Тогда логичный вопрос - в каких случаях нужно false? Зачем это?
Пример. Ты поменял расширенные данные примитива, которые не влияют на его отображение, но сам примитив поменялся. Чтобы не происходило перерисовки - вызывай RecordGraphicsModified(false)
Спасибо! Понял

Оффлайн Вильдар

  • ADN Club
  • ****
  • Сообщений: 405
  • Карма: 77
  • Skype: vildar82
Лучше использовать doc.TransactionManager.FlushGraphics(); - используется менеджер транзакций документа, а не базы данных.
А расскажите, в чем разница между TransactionManager в документе и базе(Database).
TransactionManager в документе - это класс в пространстве ApplicationServices унаследованный от TransactionManager в базе из пространства DatabaseServices.
Почитал справку, все равно не понятно, зачем сделано два класса.
Спасибо заранее! :)

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

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