Не срабатывает метод Execute в классе с IExternalCommand

Автор Тема: Не срабатывает метод Execute в классе с IExternalCommand  (Прочитано 4537 раз)

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

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

  • ADN OPEN
  • Сообщений: 45
  • Карма: 0
Доброго времени суток. Сделал Dockable pane с кнопками (ICommand). Инициализирую в ICommand класс AutoReloadExample, который вызывает класс CreationExternalCommand, который наследует интерфейс IExternalCommand. Так ,как это Dockable pane , а не Ribbon ревита - метод Execute не срабатывает. Подскажите, как вызвать метод Execute , чтобы подменить dll ?




Оффлайн Александр Игнатович

  • Administrator
  • *****
  • Сообщений: 1152
  • Карма: 338
  • Skype: alexandr.ignatovich.itc
Во-первых, то, что у тебя не вызывается метод - это где-то ошибки в твоем коде, ты его вообще вызываешь?

Во-вторых, код в ICommand у тебя в данном случае выполняется в невалидном контексте API, работа с API Revit будет приводить к крашам, повреждению моделей и т.д. Для реализации таких вещей в API есть ExternalEvent, пример можешь посмотреть в SDK Software Development Kit\Samples\ModelessDialog\ModelessForm_ExternalEvent

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

  • ADN OPEN
  • Сообщений: 45
  • Карма: 0
Во-первых, то, что у тебя не вызывается метод - это где-то ошибки в твоем коде, ты его вообще вызываешь?

Во-вторых, код в ICommand у тебя в данном случае выполняется в невалидном контексте API, работа с API Revit будет приводить к крашам, повреждению моделей и т.д. Для реализации таких вещей в API есть ExternalEvent, пример можешь посмотреть в SDK Software Development Kit\Samples\ModelessDialog\ModelessForm_ExternalEvent
Со вторым случаем знаю ,как решить. С первым , подскажите ,как вызвать метод Execute?  IExternalCommand срабатывает ,как я понял, если мы нажимаем кнопки на Ribbon ревита, а с Dockable pane , уже другая ситуация.
  public ICommand CommandOpenFormingHoles
        {
            get
            {
                if (_commandOpenFormingHoles == null)
                    _commandOpenFormingHoles = new RelayCommand(o =>
                    {
                        string path_dll = _assembly_folder_name + "FormingHoles_2020.dll";
                        string name_class = "FormingHoles.Model.FormingHoles";
                        autoReloadExample = new AutoReloadExample(path_dll, name_class);

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

  • ADN OPEN
  • Сообщений: 45
  • Карма: 0
Со вторым случаем все ок, подскажите, пожалуйста ,как вызвать метод Execute?


Оффлайн Александр Игнатович

  • Administrator
  • *****
  • Сообщений: 1152
  • Карма: 338
  • Skype: alexandr.ignatovich.itc
Ну объект ты создал, а метод кто вызывать будет?

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

  • ADN OPEN
  • Сообщений: 45
  • Карма: 0
Ну объект ты создал, а метод кто вызывать будет?
Чтобы вызвать метод Execute нужно передать главным аргументом ExternalCommandData. Откуда я могу его правильно получить?

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

  • ADN OPEN
  • Сообщений: 45
  • Карма: 0
Ну объект ты создал, а метод кто вызывать будет?
Чтобы вызвать метод Execute нужно передать главным аргументом ExternalCommandData. Откуда я могу его правильно получить?
Один вопрос: откуда могу получить ExternalCommandData ? для перегрузки метода Execute с тремя аргументами ?


Оффлайн Александр Игнатович

  • Administrator
  • *****
  • Сообщений: 1152
  • Карма: 338
  • Skype: alexandr.ignatovich.itc
Вариант первый, предпочтительный. Пересмотреть архитектуру, вызывать не метод IExternalCommand.Execute, а другой метод

Вариант второй. Если команды есть на ribbon, использовать RevitCommandId и UIApplication.PostCommand

Вариант третий. Reflection в помощь. В отличие от большинства классов в API, представляющих тонкие прокладки между миром .Net и native кодом, ExternalCommandData полноценный класс из мира .Net.
Код - C# [Выбрать]
  1. var commandDataType = typeof (ExternalCommandData);
  2.  
  3. var constructor = commandDataType.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[0], null);
  4.  
  5. var externalCommandData = (ExternalCommandData)constructor?.Invoke(null);
  6.  
  7. if (externalCommandData == null)
  8.         throw new Exception("Something went wrong");
  9.  
  10. externalCommandData.Application = uiapp;
  11. externalCommandData.JournalData = new Dictionary<string, string>();
  12. externalCommandData.View = view;

Потенциально ненадежный, т.к. внутренняя реализация может измениться