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

ADN Club => AutoCAD .NET API => Тема начата: Дмитрий Загорулькин от 17-11-2014, 13:51:03

Название: Как задать уже выбранные ранее объекты при множественном выборе объектов?
Отправлено: Дмитрий Загорулькин от 17-11-2014, 13:51:03
Здравствуйте!
Есть необходимость выбора объектов, но с уже известным заранее набором объектов. Этакий вариант изменения предыдущего выбора.
То есть, должно быть такое поведение:
- запускается метод выбора
- подсвечивается переданный набор объектов как будто их только что уже выбрали
- далее уже можно продолжать работать с этим выбором - выбирать новые или удалять из выбора объекты.
По поведению, это должно быть похоже на выбор объектов для операций в динамическом блоке:
https://screencast.autodesk.com/main/details/391e256b-00e9-45ce-a2de-1d4b4e372a25
Может быть, у кого-то есть идеи как такое можно сделать? Или уже знаете как сделать такое? Поделитесь, пожалуйста!
Я уже вроде все возможности метода Editor.GetSelection на пару с событиями объекта Editor исследовал и не нашел как такое сделать можно.
Название: Re: Как задать уже выбранные ранее объекты при множественном выборе объектов?
Отправлено: German от 17-11-2014, 14:04:41
Теоретически SetImpliedSelection(...) должен работать...
https://sites.google.com/site/bushmansnetlaboratory/translate-manual/sozdanie-i-redaktirovanie-obektov-autocad/rabota-s-vybrannymi-naborami/polucenie-nabora-predvaritelnogo-vybora
Название: Re: Как задать уже выбранные ранее объекты при множественном выборе объектов?
Отправлено: Александр Ривилис от 17-11-2014, 14:17:21
Итак. Допустим у тебя есть уже набор, в котором содержатся примитивы.
1) Запускаешь команду _SELECT и передаешь ей этот набор. Завершаешь команду. Теперь в предыдущем наборе будут эти примитивы. Их можно выбрать в команде выбора при помощи ключевого слова "_P"
2) Запускаешь асинхронно (наверное через Document.SendStringToExecute) "_P " - команда сразу не выполнится, а выполнится только после запроса к AutoCAD. Про пробел после _P не забудь.
3) Запускаешь Editor.GetSelection() - в этот момент как раз и должно попасть "_P", т.е. сначала отработает ввод предыдущего набора, а затем будет запрос к пользователю.
На 100% не уверен, но думаю что сработает. 
Название: Re: Как задать уже выбранные ранее объекты при множественном выборе объектов?
Отправлено: Дмитрий Загорулькин от 17-11-2014, 14:27:31
German, интересное предположение! Но проверка показала, что не работает такой вариант. Если есть предварительный выбор, при запуске метода Editor.GetSelection просто он же и возвращается без всякой возможности выбора вручную. По крайней мере, в моем коде именно так это работает.
Александр Наумович, ой как не хочется командные методы использовать... К тому же, набора первоначального как такового нет - есть только коллекция ObjectId объектов. Ее как-то передать в _SELECT возможно?
Название: Re: Как задать уже выбранные ранее объекты при множественном выборе объектов?
Отправлено: Александр Ривилис от 17-11-2014, 14:46:57
К тому же, набора первоначального как такового нет - есть только коллекция ObjectId объектов. Ее как-то передать в _SELECT возможно?
Конечно. Создаешь SelectionSet из коллекции ObjectId и передаёшь его (SelectionSet) в команду. Т.е.:
Код - C# [Выбрать]
  1. SelectionSet ss = SelectionSet.FromObjectIds(ids);  // ids - коллекция ObjectId
  2. ed.Command("_SELECT", ss, ""); // Код условный - зависит от того каким образом ты будешь синхронно запускать команду
Название: Re: Как задать уже выбранные ранее объекты при множественном выборе объектов?
Отправлено: Дмитрий Загорулькин от 17-11-2014, 15:53:52
По поведению, вот этот код делает то, что нужно:
Код - C# [Выбрать]
  1. SelectionSet sSet = SelectionSet.FromObjectIds(ids);
  2. ed.Command("_.select", sSet);
Но как потом получить выбранные объекты?
Как добавить фильтр выбора?
Как задать сообщения при выборе/удалении из выбора объектов?
Цитировать
2) Запускаешь асинхронно (наверное через Document.SendStringToExecute) "_P " - команда сразу не выполнится, а выполнится только после запроса к AutoCAD. Про пробел после _P не забудь.
Вызов асинхронной команды с помощью ed.CommandAsync выполняется уже после завершения всего моего командного метода, когда это уже совершенно не нужно...
Название: Re: Как задать уже выбранные ранее объекты при множественном выборе объектов?
Отправлено: Александр Ривилис от 17-11-2014, 18:04:48
Как добавить фильтр выбора?
Как задать сообщения при выборе/удалении из выбора объектов?
Ну это уж слишком много хочешь. :)
Название: Re: Как задать уже выбранные ранее объекты при множественном выборе объектов?
Отправлено: Александр Ривилис от 17-11-2014, 18:46:03
Попробуй такой вариант. Я тестировал его только в AutoCAD 2015, но есть все предпосылки, что он будет работать и в предыдущих версиях:
Код - C# [Выбрать]
  1. using System;
  2. using Autodesk.AutoCAD.Runtime;
  3. using Autodesk.AutoCAD.Internal; // Нужно для Utils.SelectObjects
  4. using Autodesk.AutoCAD.ApplicationServices;
  5. using Autodesk.AutoCAD.DatabaseServices;
  6. using Autodesk.AutoCAD.Geometry;
  7. using Autodesk.AutoCAD.EditorInput;
  8. using AcRx = Autodesk.AutoCAD.Runtime;
  9. using AcAp = Autodesk.AutoCAD.ApplicationServices;
  10. using AcDb = Autodesk.AutoCAD.DatabaseServices;
  11. using AcGe = Autodesk.AutoCAD.Geometry;
  12. using AcEd = Autodesk.AutoCAD.EditorInput;
  13. using AcIt = Autodesk.AutoCAD.Internal;
  14.  
  15. [assembly: CommandClass(typeof(TestSelectionSet.MyCommands))]
  16.  
  17. namespace TestSelectionSet
  18. {
  19.   public class MyCommands
  20.   {
  21.     [CommandMethod("TestAddSelection")]
  22.     public void TestAddSelection()
  23.     {
  24.       AcAp.Document doc = AcAp.Application.DocumentManager.MdiActiveDocument;
  25.       if (doc == null) return;
  26.       AcEd.Editor ed = doc.Editor;
  27.       ObjectId[] ids = GetObjectIdFromUser();
  28.       if (ids != null && ids.Length != 0) {
  29.         // Устанавливаем предварительный набор
  30.         // (вместо команды _SELECT)
  31.         AcIt.Utils.SelectObjects(ids);
  32.         // Первое запрос фальшивый - только для того, чтобы "проглотить"
  33.         // набор предварительного выбора
  34.         AcEd.PromptSelectionResult resSel = ed.GetSelection();
  35.         doc.SendStringToExecute("_P ", false, false, false);
  36.         // Тут возможен вариант и с фильтром
  37.         resSel = ed.GetSelection();
  38.         if (resSel.Status == PromptStatus.OK)
  39.         {
  40.           ed.WriteMessage("\nВыбрано {0} объектов.", resSel.Value.Count);
  41.         }
  42.       }
  43.     }
  44.     /// Тестовая функция, которая возвращает массив ObjectId
  45.     public ObjectId[] GetObjectIdFromUser()
  46.     {
  47.       AcAp.Document doc = AcAp.Application.DocumentManager.MdiActiveDocument;
  48.       if (doc == null) return null;
  49.       AcEd.Editor ed = doc.Editor;
  50.       AcEd.PromptSelectionResult resSel = ed.GetSelection();
  51.       if (resSel.Status == PromptStatus.OK && resSel.Value.Count != 0)
  52.         return resSel.Value.GetObjectIds();
  53.       else
  54.         return null;
  55.     }
  56.   }
  57. }
Название: Re: Как задать уже выбранные ранее объекты при множественном выборе объектов?
Отправлено: Дмитрий Загорулькин от 17-11-2014, 19:14:00
Да! Все работает как надо и в 2014 и в 2015 версиях! И с фильтром и с сообщениями! Гениально! Спасибо большое! :)
Название: Re: Как задать уже выбранные ранее объекты при множественном выборе объектов?
Отправлено: Александр Ривилис от 17-11-2014, 19:27:49
Гениально!
Да ладно уж. Стесняюсь. (https://adn-cis.org/forum/proxy.php?request=http%3A%2F%2Fimg-fotki.yandex.ru%2Fget%2F4412%2F56522409.7%2F0_63953_b2ab9d24_S&hash=8e04680a54dfc5c3162fffba8daa60eb)
Название: Re: Как задать уже выбранные ранее объекты при множественном выборе объектов?
Отправлено: Дмитрий Загорулькин от 17-11-2014, 20:03:02
Погонял код и так и эдак, поэкспериментировал. Выяснил, что Utils.SelectObjects можно заменить на ed.SetImpliedSelection - работает одинаково. Ну а в остальном - из песни слов не выкинешь, работает только в таком варианте :)
Я еще думал, что получится adoc.SendStringToExecute("_P ", false, false, false) заменить на ed.SelectPrevious() - но не вышло, хотя, вроде бы одинаковые функции выполняют. А  не, понял в чем разница :)
Название: Re: Как задать уже выбранные ранее объекты при множественном выборе объектов?
Отправлено: Александр Ривилис от 17-11-2014, 23:00:00
Я еще думал, что получится adoc.SendStringToExecute("_P ", false, false, false) заменить на ed.SelectPrevious() - но не вышло, хотя, вроде бы одинаковые функции выполняют.
Функции выполняет как раз разные. Первое просто вводит в командную строку "_P ", причем именно тогда, когда AutoCAD ожидает от пользователя выбор примитивов или ключевое слово. Второе же просто возвращает набор предыдущего выбора.
Название: Re: Как задать уже выбранные ранее объекты при множественном выборе объектов?
Отправлено: Дмитрий Загорулькин от 18-11-2014, 10:05:22
Да, я понял, спасибо :)
Цитировать
причем именно тогда, когда AutoCAD ожидает от пользователя выбор примитивов или ключевое слово
Кстати, даже если бы не было этой особенности, можно было бы подписаться на событие ed.PromptingForSelection (или ed.PromptedForSelection) и в нем запустить (sender as Editor).Document.SendStringToExecute.