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

ADN Club => AutoCAD .NET API => Тема начата: Александр Пекшев aka Modis от 12-03-2018, 11:11:48

Название: Скрыть текст "До" при использовании InplaceTextEditor
Отправлено: Александр Пекшев aka Modis от 12-03-2018, 11:11:48
Всем привет. Накидал тут тестовый проектик с использованием 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. }
При таких условиях при редактировании текста я вижу новый текст и старый:

(https://s18.postimg.org/h2yv5os6t/Screenshot_10.png) (https://postimg.org/image/h2yv5os6t/)

Есть ли способ избежать отображение текста "ДО"? Мне особо это не помешает, но хотелось бы чтобы было чистенько
Название: Re: Скрыть текст "До" при использовании InplaceTextEditor
Отправлено: Александр Пекшев aka Modis от 12-03-2018, 11:25:24
Один из вариантов (плохой правда вариант) - скрыть весь 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. }
Ну это плохой вариант, так как весь блок не видно в момент редактирования текста
Название: Re: Скрыть текст "До" при использовании InplaceTextEditor
Отправлено: Александр Пекшев aka Modis от 12-03-2018, 11:42:24
На пару с Вильдаром нашли вариант рабочий:
Код - 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(); Не вызовет ли это "тормоза" когда объектов в модели будет очень много?
Пока не помечаю как ответ
Название: Re: Скрыть текст "До" при использовании InplaceTextEditor
Отправлено: Вильдар от 12-03-2018, 11:55:07
Из трех вариантов, я бы выбрал первый, когда видно серый исходный текст на заднем плане - это больше на фичу похоже.
Название: Re: Скрыть текст "До" при использовании InplaceTextEditor
Отправлено: Дмитрий Загорулькин от 12-03-2018, 13:26:59
Единственное, что смущает - частое использование ed.Regen(); Не вызовет ли это "тормоза" когда объектов в модели будет очень много?
Вызовет. Зависит от чертежа, конечно.
RecordGraphicsModified пробовали? FlushGraphics?
Или начальное содержимое текста сохранять в переменной, очищать его и потом уже пустым передавать в InplaceTextEditor. Если text.IsModified не выполняется - восстановить исходное значение.
Название: Re: Скрыть текст "До" при использовании InplaceTextEditor
Отправлено: Александр Пекшев aka Modis от 12-03-2018, 17:32:58
RecordGraphicsModified пробовали? FlushGraphics?
Пробовал - нет эффекта. Только ed.Regen();
Или начальное содержимое текста сохранять в переменной, очищать его и потом уже пустым передавать в InplaceTextEditor. Если text.IsModified не выполняется - восстановить исходное значение
Тогда в редактор передастся текст с пустым значением =) Тоже не вариант
Вызовет. Зависит от чертежа, конечно.
Вот это и грустно
Название: Re: Скрыть текст "До" при использовании InplaceTextEditor
Отправлено: Александр Ривилис от 12-03-2018, 17:47:15
Если ты редактируешь текст внутри блока, то помочь может или Editor.Regen() или RecordGraphicsModified плюс QueueForGraphicsFlush, но (!!!) для всех вставок этого блока и не внутри транзакции.
Название: Re: Скрыть текст "До" при использовании InplaceTextEditor
Отправлено: Александр Пекшев aka Modis от 12-03-2018, 18:08:30
или RecordGraphicsModified плюс QueueForGraphicsFlush
Попробовал - не помогло. НО
но (!!!) для всех вставок этого блока и не внутри транзакции
Я не понял - как я это могу сделать НЕ внутри транзакции?
Название: Re: Скрыть текст "До" при использовании InplaceTextEditor
Отправлено: Александр Пекшев aka Modis от 12-03-2018, 18:15:36
Все! Получилось! В одной транзакции, кстати. Вся проблема у меня был в том, что я метод RecordGraphicsModified вызывал с аргументом false, а надо было true (кстати, в чем разница?)

Извините, вам запрещён просмотр содержимого спойлеров.
Название: Re: Скрыть текст "До" при использовании InplaceTextEditor
Отправлено: Александр Пекшев aka Modis от 12-03-2018, 18:18:43
Что самое интересное - работает и так:
Код - C# [Выбрать]
  1. selectedBlock.RecordGraphicsModified(true);
  2. doc.TransactionManager.FlushGraphics();
и так:
Код - C# [Выбрать]
  1. selectedBlock.RecordGraphicsModified(true);
  2. db.TransactionManager.QueueForGraphicsFlush();
Лично для меня не ясно в чем разница этих методов
Название: Re: Скрыть текст "До" при использовании InplaceTextEditor
Отправлено: Александр Ривилис от 12-03-2018, 18:19:03
Вся проблема у меня был в том, что я метод RecordGraphicsModified вызывал с аргументом false, а надо было true (кстати, в чем разница?)
Разница в том, что при false ты отмечал, что графика не менялась, а при true отмечаешь, что она изменилась. Соответственно TransactionManager.QueueForGraphicsFlush() делать было нечего - чего перерисовывать если графика не меняется.
Название: Re: Скрыть текст "До" при использовании InplaceTextEditor
Отправлено: Александр Ривилис от 12-03-2018, 18:20:15
Что самое интересное - работает и так:
Код - C# [Выбрать]
  1. selectedBlock.RecordGraphicsModified(true);
  2. doc.TransactionManager.FlushGraphics();
и так:
Код - C# [Выбрать]
  1. selectedBlock.RecordGraphicsModified(true);
  2. db.TransactionManager.QueueForGraphicsFlush();
Лично для меня не ясно в чем разница этих методов
Лучше использовать doc.TransactionManager.FlushGraphics(); - используется менеджер транзакций документа, а не базы данных.
Название: Re: Скрыть текст "До" при использовании InplaceTextEditor
Отправлено: Александр Пекшев aka Modis от 12-03-2018, 18:20:17
Вся проблема у меня был в том, что я метод RecordGraphicsModified вызывал с аргументом false, а надо было true (кстати, в чем разница?)
Разница в том, что при false ты отмечал, что графика не менялась, а при true отмечаешь, что она изменилась. Соответственно TransactionManager.QueueForGraphicsFlush() делать было нечего - чего перерисовывать если графика не меняется.
Тогда логичный вопрос - в каких случаях нужно false? Зачем это?
Название: Re: Скрыть текст "До" при использовании InplaceTextEditor
Отправлено: Александр Ривилис от 12-03-2018, 18:21:45
Я не понял - как я это могу сделать НЕ внутри транзакции?
Имелось в виду QueueForGraphicsFlush вне транзакции. Но если сработало внутри транзакции, то и замечательно.
Название: Re: Скрыть текст "До" при использовании InplaceTextEditor
Отправлено: Александр Ривилис от 12-03-2018, 18:23:37
Тогда логичный вопрос - в каких случаях нужно false? Зачем это?
Пример. Ты поменял расширенные данные примитива, которые не влияют на его отображение, но сам примитив поменялся. Чтобы не происходило перерисовки - вызывай RecordGraphicsModified(false)
Название: Re: Скрыть текст "До" при использовании InplaceTextEditor
Отправлено: Александр Пекшев aka Modis от 12-03-2018, 18:25:10
Тогда логичный вопрос - в каких случаях нужно false? Зачем это?
Пример. Ты поменял расширенные данные примитива, которые не влияют на его отображение, но сам примитив поменялся. Чтобы не происходило перерисовки - вызывай RecordGraphicsModified(false)
Спасибо! Понял
Название: Re: Скрыть текст "До" при использовании InplaceTextEditor
Отправлено: Вильдар от 13-03-2018, 10:38:59
Лучше использовать doc.TransactionManager.FlushGraphics(); - используется менеджер транзакций документа, а не базы данных.
А расскажите, в чем разница между TransactionManager в документе и базе(Database).
TransactionManager в документе - это класс в пространстве ApplicationServices унаследованный от TransactionManager в базе из пространства DatabaseServices.
Почитал справку, все равно не понятно, зачем сделано два класса.
Спасибо заранее! :)
Название: Re: Скрыть текст "До" при использовании InplaceTextEditor
Отправлено: Александр Ривилис от 13-03-2018, 13:22:05
TransactionManager для документа нельзя использовать с базами открытыми не как документы (т.е. через ReadDwgFile). Для таких баз допустимы только TransactionManager для баз. TransactionManager для баз может не актуализировать изображение на экране (особенно если база не является базой активного документа), а TransactionManager для документа обязан это сделать. В общем случае TransactionManager для документа выполняет тоже, что и TransactionManager для базы и плюс специфические для документа действия. Как-то так.