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

ADN Club => Revit API => Тема начата: Alex25 от 28-09-2020, 16:13:06

Название: Не срабатывает метод Execute в классе с IExternalCommand
Отправлено: Alex25 от 28-09-2020, 16:13:06
Доброго времени суток. Сделал Dockable pane с кнопками (ICommand). Инициализирую в ICommand класс AutoReloadExample, который вызывает класс CreationExternalCommand, который наследует интерфейс IExternalCommand. Так ,как это Dockable pane , а не Ribbon ревита - метод Execute не срабатывает. Подскажите, как вызвать метод Execute , чтобы подменить dll ?


(https://i.postimg.cc/cgdB0xX5/20.png) (https://postimg.cc/cgdB0xX5)
Название: Re: Не срабатывает метод Execute в классе с IExternalCommand
Отправлено: Александр Игнатович от 28-09-2020, 18:17:39
Во-первых, то, что у тебя не вызывается метод - это где-то ошибки в твоем коде, ты его вообще вызываешь?

Во-вторых, код в ICommand у тебя в данном случае выполняется в невалидном контексте API, работа с API Revit будет приводить к крашам, повреждению моделей и т.д. Для реализации таких вещей в API есть ExternalEvent, пример можешь посмотреть в SDK Software Development Kit\Samples\ModelessDialog\ModelessForm_ExternalEvent
Название: Re: Не срабатывает метод Execute в классе с IExternalCommand
Отправлено: Alex25 от 28-09-2020, 18:38:55
Во-первых, то, что у тебя не вызывается метод - это где-то ошибки в твоем коде, ты его вообще вызываешь?

Во-вторых, код в 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);
Название: Re: Не срабатывает метод Execute в классе с IExternalCommand
Отправлено: Alex25 от 28-09-2020, 19:01:13
Со вторым случаем все ок, подскажите, пожалуйста ,как вызвать метод Execute?
(https://i.postimg.cc/dDvgB077/30.png) (https://postimg.cc/dDvgB077)
Название: Re: Не срабатывает метод Execute в классе с IExternalCommand
Отправлено: Александр Игнатович от 28-09-2020, 20:08:21
Ну объект ты создал, а метод кто вызывать будет?
Название: Re: Не срабатывает метод Execute в классе с IExternalCommand
Отправлено: Alex25 от 29-09-2020, 08:36:45
Ну объект ты создал, а метод кто вызывать будет?
Чтобы вызвать метод Execute нужно передать главным аргументом ExternalCommandData. Откуда я могу его правильно получить?
Название: Re: Не срабатывает метод Execute в классе с IExternalCommand
Отправлено: Alex25 от 29-09-2020, 10:28:38
Ну объект ты создал, а метод кто вызывать будет?
Чтобы вызвать метод Execute нужно передать главным аргументом ExternalCommandData. Откуда я могу его правильно получить?
Один вопрос: откуда могу получить ExternalCommandData ? для перегрузки метода Execute с тремя аргументами ?
(https://i.postimg.cc/R32tSCF1/40.png) (https://postimg.cc/R32tSCF1)
Название: Re: Не срабатывает метод Execute в классе с IExternalCommand
Отправлено: Александр Игнатович от 30-09-2020, 00:10:51
Вариант первый, предпочтительный. Пересмотреть архитектуру, вызывать не метод 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;

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