Контекстное меню таблицы и выбранная ячейка

Автор Тема: Контекстное меню таблицы и выбранная ячейка  (Прочитано 9645 раз)

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

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

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

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Всем привет)
Имеем контекстное меню для таблицы:
Извините, вам запрещён просмотр содержимого спойлеров.

В обработке события выпадения меню PopUp отключаю меню если выбрано более одной таблицы:
Извините, вам запрещён просмотр содержимого спойлеров.

Предыдущие коды свернул в спойлер, т.к. они не сильно важны. Теперь переходим к сути:
Когда мы вызываем контекстное меню для таблицы, то у нас может быть минимум два варианта - просто выбрана таблица или выбрана ячейка в таблице:



По идее - это разные меню: первое для таблицы, второе для ячейки. Однако приложенный выше кода добавляет мой пункт и туда и туда... ну да хрен с ним =)
Вопрос вот в чем - можно ли, если меню вызвано вторым вариантом, как-то получить ту самую ячейку, для которой вызвано меню? Точнее - там CellRange должен быть, но это не суть важно.
Мне для работы функции нужно получить строку. Для этого пользователь должен выбрать сначала таблицу, затем ткнуть в ячейку. И если для первого варианта это нормально, то для второго - не логично и неудобно. Строка (ячейка) выбрана, но приходится все-равно выбирать ее еще раз
Код - C# [Выбрать]
  1. private static void AddProductToTable(object sender, EventArgs e)
  2. {
  3.     var doc = AcApp.DocumentManager.MdiActiveDocument;
  4.     var db = doc.Database;
  5.     var ed = doc.Editor;
  6.     var psr = ed.SelectImplied();
  7.  
  8.     if (psr.Status == PromptStatus.OK)
  9.     {
  10.         ObjectIdCollection reqObjs;
  11.         if (psr.Status == PromptStatus.OK)
  12.             reqObjs =
  13.               new ObjectIdCollection(
  14.               psr.Value.GetObjectIds()
  15.             );
  16.         else
  17.             reqObjs = new ObjectIdCollection();
  18.         // Clear the pickfirst set...
  19.         ed.SetImpliedSelection(new ObjectId[0]);
  20.         // Количество уже проверено в PopUp
  21.         using (doc.LockDocument())
  22.         {
  23.             using (var tr = db.TransactionManager.StartTransaction())
  24.             {
  25.                 var tbl = (Table)tr.GetObject(reqObjs[0], OpenMode.ForWrite);
  26.                 int? selectedRow = null;
  27.  
  28.                 // Проверяем была ли выбрана ячейка
  29.                 // ????????????????????????????????
  30.                 //
  31.  
  32.                 // Если ячейка не была выбрана, то нужно выбрать
  33.                 if (selectedRow == null)
  34.                 {
  35.                     var ppo = new PromptPointOptions("\nВыберите строку: ");
  36.                     var end = false;
  37.                     var vector = new Vector3d(0.0, 0.0, 1.0);
  38.                     while (end == false)
  39.                     {
  40.                         var ppr = ed.GetPoint(ppo);
  41.                         if (ppr.Status != PromptStatus.OK) return;
  42.                         try
  43.                         {
  44.                             var tblhittestinfo = tbl.HitTest(ppr.Value, vector);
  45.                             if (tblhittestinfo.Type == TableHitTestType.Cell)
  46.                             {
  47.                                 selectedRow = tblhittestinfo.Row;
  48.                                 end = true;
  49.                             }
  50.                         } // try
  51.                         catch
  52.                         {
  53.                             MpMsgWin.Show("Не попали в ячейку!");
  54.                         }
  55.                     } // while
  56.                 }
  57.             }
  58.         }
  59.     }
  60. }
« Последнее редактирование: 06-09-2015, 16:17:31 от Александр Ривилис »

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

  • Administrator
  • *****
  • Сообщений: 13886
  • Карма: 1788
  • Рыцарь ObjectARX
  • Skype: rivilis
1. Не увлекайся спойлерами. В имени спойлера нельзя использовать двойные кавычки.
2. Посмотри этот пример. Думаю он тебе поможет: Использование события выбора ячейки в таблице
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13886
  • Карма: 1788
  • Рыцарь ObjectARX
  • Skype: rivilis
Ну и еще такой код может быть полезен:
Код - C# [Выбрать]
  1. using System;
  2. using Autodesk.AutoCAD.Runtime;
  3. using Autodesk.AutoCAD.ApplicationServices;
  4. using Autodesk.AutoCAD.DatabaseServices;
  5. using Autodesk.AutoCAD.Geometry;
  6. using Autodesk.AutoCAD.EditorInput;
  7. using Autodesk.AutoCAD.Windows;
  8.  
  9. [assembly: CommandClass(typeof(Rivilis.TableUtils))]
  10.  
  11. namespace Rivilis
  12. {
  13.   public class TableUtils
  14.   {
  15.     [CommandMethod("TabSubSel",
  16.       CommandFlags.Modal | CommandFlags.UsePickSet | CommandFlags.Redraw)]
  17.     public void TabSubSel()
  18.     {
  19.       Document doc = Application.DocumentManager.MdiActiveDocument;
  20.       if (doc == null) return;
  21.       Editor ed = doc.Editor;
  22.       PromptSelectionResult res = ed.SelectImplied();
  23.       if (res.Status != PromptStatus.OK)
  24.       {
  25.         ed.WriteMessage("\nНичего не выбрано!");
  26.         return;
  27.       }
  28.       if (res.Value.Count == 1 &&
  29.         res.Value.GetObjectIds()[0].ObjectClass.IsDerivedFrom(
  30.         RXClass.GetClass(typeof(Table))))
  31.       {
  32.         using (Table tab = res.Value.GetObjectIds()[0].Open(OpenMode.ForRead) as Table)
  33.         {
  34.           if (tab.HasSubSelection)
  35.           {
  36.             CellRange cells = tab.SubSelection;
  37.             if (cells.IsSingleCell)
  38.             {
  39.               ed.WriteMessage("\nЯчейка:");
  40.               ed.WriteMessage("\n\tСтрока = {0} Колонка = {1}",
  41.                 cells.TopRow, cells.LeftColumn);
  42.             }
  43.             else
  44.             {
  45.               ed.WriteMessage("\nДиапазон ячеек:");
  46.               ed.WriteMessage("\n\tВерхняя строка = {0} Нижняя строка = {1}",
  47.                 cells.TopRow, cells.BottomRow);
  48.               ed.WriteMessage("\n\tЛевая колонка = {0} Правая колонка = {1}",
  49.                 cells.LeftColumn, cells.RightColumn);
  50.             }
  51.           }
  52.           else
  53.           {
  54.             ed.WriteMessage("\nНи одна ячейка не выбрана!");
  55.           }
  56.         }
  57.       }
  58.       else
  59.       {
  60.         ed.WriteMessage("\nВыбрано больше одного примитива или не выбрана таблица!");
  61.       }
  62.     }
  63.  
  64.     // Добавление контекстного меню
  65.     [CommandMethod("ContextMenuExtTest")]
  66.     static public void ContextMenuExtTest()
  67.     {
  68.       ContextMenuExtension contectMenu = new ContextMenuExtension();
  69.       MenuItem item0 = new MenuItem("Что выбрано в таблице?");
  70.       item0.Click += new EventHandler(Table_Select);
  71.       contectMenu.MenuItems.Add(item0);
  72.       Application.AddObjectContextMenuExtension(
  73.         RXClass.GetClass(typeof(Table)), contectMenu);
  74.  
  75.     }
  76.     // Обработчик пункта меню
  77.     static void Table_Select(object sender, EventArgs e)
  78.     {
  79.       Application.DocumentManager.MdiActiveDocument
  80.         .SendStringToExecute("_TabSubSel ", false, false, false);
  81.     }
  82.   }
  83. }
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Александр Ривилис, ваш пример конечно-же работает) Но меня не оставляет в покое другое:
в том примере, что я выше описывал - я пытался сделать тоже самое, но сразу в обработчике события Click
Код - C# [Выбрать]
  1. private static void AddProductToTable(object sender, EventArgs e)
  2. {
  3.     var doc = AcApp.DocumentManager.MdiActiveDocument;
  4.     var db = doc.Database;
  5.     var ed = doc.Editor;
  6.     var psr = ed.SelectImplied();
  7.  
  8.     if (psr.Status == PromptStatus.OK)
  9.     {
  10.         ObjectIdCollection reqObjs;
  11.         if (psr.Status == PromptStatus.OK)
  12.             reqObjs =
  13.               new ObjectIdCollection(
  14.               psr.Value.GetObjectIds()
  15.             );
  16.         else
  17.             reqObjs = new ObjectIdCollection();
  18.         // Clear the pickfirst set...
  19.         ed.SetImpliedSelection(new ObjectId[0]);
  20.         // Количество уже проверено в PopUp
  21.         using (doc.LockDocument())
  22.         {
  23.             using (var tr = db.TransactionManager.StartTransaction())
  24.             {
  25.                 var tbl = (Table)tr.GetObject(reqObjs[0], OpenMode.ForWrite);
  26.                 int? selectedRow = null;
  27.                
  28.                 if (tbl.HasSubSelection)
  29.                 {
  30.                     var cells = tbl.SubSelection;
  31.                     if (cells.IsSingleCell)
  32.                     {
  33.                         selectedRow = cells.TopRow;
  34.                     }
  35.                 }
  36.  
  37.                 // Если ячейка не была выбрана, то нужно выбрать
  38.                 if (selectedRow == null)
  39.                 {
  40.                     var ppo = new PromptPointOptions("\nВыберите строку: ");
  41.                     var end = false;
  42.                     var vector = new Vector3d(0.0, 0.0, 1.0);
  43.                     while (end == false)
  44.                     {
  45.                         var ppr = ed.GetPoint(ppo);
  46.                         if (ppr.Status != PromptStatus.OK) return;
  47.                         try
  48.                         {
  49.                             var tblhittestinfo = tbl.HitTest(ppr.Value, vector);
  50.                             if (tblhittestinfo.Type == TableHitTestType.Cell)
  51.                             {
  52.                                 selectedRow = tblhittestinfo.Row;
  53.                                 end = true;
  54.                             }
  55.                         } // try
  56.                         catch
  57.                         {
  58.                             MpMsgWin.Show("Не попали в ячейку!");
  59.                         }
  60.                     } // while
  61.                     // AddProduct
  62.                 }
  63.                 MpBSpecificationFunction.AddProductToTableRow(tr, tbl, selectedRow.Value);
  64.             }
  65.         }
  66.     }
  67. }
Но в этом случае значение tbl.HasSubSelection всегда false. В чем разница?

Отмечено как Решение Александр Пекшев aka Modis 06-09-2015, 20:23:52

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

  • Administrator
  • *****
  • Сообщений: 13886
  • Карма: 1788
  • Рыцарь ObjectARX
  • Skype: rivilis
Но в этом случае значение tbl.HasSubSelection всегда false. В чем разница?
А самому сравнить слабо?
Подозреваю, что проблема в этой строке:
ed.SetImpliedSelection(new ObjectId[0]);
Ну и еще ты открываешь таблицу для записи.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Подозреваю, что проблема в этой строке:
ed.SetImpliedSelection(new ObjectId[0]);
А слона-то я и не приметил) Александр, спасибо вам за вашу наблюдательность! Действительно - проблема именно в этом была
Ну и еще ты открываешь таблицу для записи.
Ну тут правильно - я буду ее изменять

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

  • Administrator
  • *****
  • Сообщений: 13886
  • Карма: 1788
  • Рыцарь ObjectARX
  • Skype: rivilis
Ну тут правильно - я буду ее изменять
Если на 100% не уверен, что будешь менять - открывай для чтения, и делай UpgradeOpen перед тем, как изменять. Особенно если используешь редактор для выбора примитива.
P.S.: А вариант с UCS != WCS ты игнорируешь как класс?
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Если на 100% не уверен, что будешь менять - открывай для чтения, и делай UpgradeOpen перед тем, как изменять. Особенно если используешь редактор для выбора примитива.
Спасибо за совет - так и поступлю
P.S.: А вариант с UCS != WCS ты игнорируешь как класс?
Есть вещи, про которые не задумываешься, пока не столкнешься =) Это вот тот самый момент - пока вы не написали, я даже и не думал пробовать сменить ПСК. Попробовал и да - нужно этот момент тоже обработать.

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

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