Передача пользовательских параметров в обработчик событий Editor

Автор Тема: Передача пользовательских параметров в обработчик событий Editor  (Прочитано 2972 раз)

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

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

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

  • ADN OPEN
  • Сообщений: 47
  • Карма: 0
Добрый день! Необходимо передать в обработчик событий Editor какие-либо свои данные, ссылки на функции и пр. Здесь на форуме я видел решение посредством использования глобальной переменной. А есть ли какой-то иной способ, без задействования глобальных переменных?

Онлайн avc

  • ADN Club
  • *****
  • Сообщений: 808
  • Карма: 166
    • Мои плагины к Автокаду
Любое статическое свойство любого класса доступно в любом месте вашего кода. Вы вообще о каких глобальных переменных? термин из VBA?

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

  • ADN OPEN
  • Сообщений: 47
  • Карма: 0
Любое статическое свойство любого класса доступно в любом месте вашего кода. Вы вообще о каких глобальных переменных? термин из VBA?
Не уверен, что правильно применяю терминологию в контексте NET. Ввиду объемности кода разбиваю его по модулям. Процедуры и функции делаю вне классов. Одна из таких процедур - обработчик событий Editor. То есть эта процедура не принадлежит классу, а реализована на уровне соответствующего модуля. Есть ли возможность для такой процедуры получать пользовательские данные, без использования переменных, объявленных также на уровне модуля?

Онлайн avc

  • ADN Club
  • *****
  • Сообщений: 808
  • Карма: 166
    • Мои плагины к Автокаду
На C# не может быть кода все классов. Если на бейсике для .Net это не так, то я не в теме. И вопрос не по API Автокада, а по конкретному языку. Или вы вообще о каком языке пишете?
В любом случае в обработчике событий надо как можно меньше обращаться к сторонним данным, использовать по возможности то, что передано через параметры. В противном случае надо очень тщательно продумывать все варианты параллельных многократных вызовов процедур. Так что будьте на чеку.

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

  • ADN OPEN
  • Сообщений: 47
  • Карма: 0
VB.NET, там возможно создание процедур и функций вне классов. А использование внешней функции, передаваемой по ссылке, мне необходимо что бы избежать дублирования кода. Речь идет об использовании PointMonitor для выполнения построений, которые после подтверждения пользователем будут окончательно применены к чертежу. Иначе придется писать две практически одинаковые функции. Еще хуже, когда необходимая функция включает достаточно большое количество кода.

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Ввиду объемности кода разбиваю его по модулям. Процедуры и функции делаю вне классов. Одна из таких процедур - обработчик событий Editor. То есть эта процедура не принадлежит классу, а реализована на уровне соответствующего модуля. Есть ли возможность для такой процедуры получать пользовательские данные, без использования переменных, объявленных также на уровне модуля?
Ничего не понял. Хоть глоссарий вводить надо: Что такое модуль? Что такое процедура, функция?
Не уверен, что правильно применяю терминологию в контексте NET.
Вот именно! Поэтому, код, даже в самом упрощённом виде, будет лучше тысячи слов ;)

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

  • ADN OPEN
  • Сообщений: 47
  • Карма: 0
Код - vb.net [Выбрать]
  1. '' Запрос линии или сегмента полилинии
  2.     '' Описание проблемы см. в следующей процедуре
  3.  
  4.     Public Sub QueryLine(ByVal acEditor As Editor,
  5.                          ByRef acLineId As ObjectId,
  6.                          ByRef acLinePickPoint As Point3d,
  7.                          ByRef acCommandSuccess As Boolean)
  8.  
  9.         '' Определение параметров запроса ПРИМИТИВА
  10.         Dim prmtEntityOpts As PromptEntityOptions = New PromptEntityOptions("")
  11.         prmtEntityOpts.Message = "Укажите линию или полилинию"
  12.         prmtEntityOpts.SetRejectMessage("Выбран примитив недопустимого типа")
  13.         prmtEntityOpts.AllowNone = False
  14.         prmtEntityOpts.AllowObjectOnLockedLayer = True
  15.  
  16.         '' Определение необходимых инструментов запроса
  17.         Dim acEventSelection = New PromptForEntityEndingEventHandler(AddressOf Event_SelectEntity)
  18.         Dim prmtEntityResult As PromptEntityResult
  19.  
  20.         '' Выполнение запроса ПРИМИТИВА
  21.         AddHandler acEditor.PromptForEntityEnding, acEventSelection
  22.         prmtEntityResult = acEditor.GetEntity(prmtEntityOpts)
  23.         RemoveHandler acEditor.PromptForEntityEnding, acEventSelection
  24.  
  25.         '' Оценка успешности выполнения запроса
  26.         acCommandSuccess = prmtEntityResult.Status = PromptStatus.OK
  27.         If Not acCommandSuccess Then Return
  28.  
  29.         '' Возвращение результата пользовательского выбора
  30.         acLineId = prmtEntityResult.ObjectId
  31.         acLinePickPoint = prmtEntityResult.PickedPoint
  32.     End Sub
  33.  
  34.     Private Sub Event_SelectEntity_CornerLine(ByVal Sender As Object,
  35.                                               ByVal acResultArgs As PromptForEntityEndingEventArgs)
  36.  
  37.         '' Объявление внутренних переменных
  38.         Dim acEditor As Editor = CType(Sender, Editor)
  39.  
  40.         Dim acSelObjId As ObjectId = acResultArgs.Result.ObjectId
  41.         Dim acSelObjPnt As Point3d = acResultArgs.Result.PickedPoint
  42.  
  43.         '' Здесь мы анализируем свойства выделенной кривой и на их основании определяем, подходит кривая или нет
  44.         '' Одно из условий - при повторном использовании процедуры выбора, выбранная кривая не должна быть той же самой, что и предыдущая
  45.         '' То есть должна быть в рамках исполнения команды уникальной из выбранных пользователем
  46.         '' Как сюда передать ObjectId ранее выбранной кривой для проверки на Equal ???
  47.  
  48.         '' Вообще-то это частность. В общем случае сюда же нужно засунуть процедуру на предварительную отрисовку результата выполнения
  49.         '' моей команды "на лету" в зависимости от примитива, находящегося под курсором (для исключения дублирования длинного кода)
  50.  
  51.         '' Можно конечно через переменную, объявленную уровнем выше процедуры или функции, в рамках того же класса
  52.         '' Но тогда нужно отдельно ее контролировать. Лучше и чище было бы получить ее в качестве аргумента данной функции.
  53.         '' Экзотический способ пометки уже выбранной кривой пользовательским свойством - тоже как то громоздко и ненадежно.
  54.         '' Что скажут уважемые гуру ?
  55.  
  56.         Dim acCheckCode = ... '' Здесь должна быть функция проверки
  57.  
  58.         '' Если оценка отрицательная объекта - удаляем примитив из выбора
  59.         If acCheckCode <> CODE_CURVE_IS_VALID Then
  60.             acResultArgs.RemoveSelectedObject()
  61.             EditorMsg(acEditor, msa_Curve_Analysis_Result(acCheckCode))
  62.         End If
  63.  
  64.     End Sub

Отмечено как Решение Phil 26-03-2018, 16:53:09

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
'' Можно конечно через переменную, объявленную уровнем выше процедуры или функции, в рамках того же класса
        '' Но тогда нужно отдельно ее контролировать. Лучше и чище было бы получить ее в качестве аргумента данной функции.
Никак ты её в качестве аргумента не передашь - всё что передаётся регламентировано в AutoCAD .NET API. Так что не придумывай - передавай через глобальную переменную.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение