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

ADN Club => Revit API => Тема начата: Пашин Евгений от 19-11-2015, 09:27:31

Название: Запуск команды из формы WPF
Отправлено: Пашин Евгений от 19-11-2015, 09:27:31
Добрый день!

Ищу пример того, как из формы WPF по нажатию кнопки запустилась команда, которую я создал в классе.

Код команды в классе:
Код - vb.net [Выбрать]
  1. <Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.ReadOnly)> _
  2. Public Class WPF_Form_Show
  3.  
  4.     Implements Autodesk.Revit.UI.IExternalCommand
  5.  
  6.     Public Function Execute(ByVal commandData As Autodesk.Revit.UI.ExternalCommandData, _
  7.             ByRef message As String, ByVal elements As Autodesk.Revit.DB.ElementSet) _
  8.             As Autodesk.Revit.UI.Result Implements Autodesk.Revit.UI.IExternalCommand.Execute
  9.  
  10.         Dim myNewForm As New MainWindow(commandData)
  11.         myNewForm.ShowDialog()
  12.  
  13.         Return Autodesk.Revit.UI.Result.Succeeded
  14.     End Function
  15.  
  16. End Class
  17.  

То есть суть сводится к тому, что по нажатию кнопки на форме WPF, я хочу открыть другую форму WPF, но не напрямую, а через запуск команды в классе!
Название: Re: Запуск команды из формы WPF
Отправлено: Антон Останин от 19-11-2015, 09:35:57
Если знаете ее GUID, то можно так:
Код - C# [Выбрать]
  1.            string commandGuid = "a9873047-014a-4fba-b46f-91bd55fa5333";
  2.             RevitCommandId commandId = RevitCommandId.LookupCommandId(commandGuid );
  3.             if (commandId==null) return;
  4.             u_app.PostCommand(commandId);
  5.  
Название: Re: Запуск команды из формы WPF
Отправлено: Виктор Чекалин от 19-11-2015, 10:13:20
То есть суть сводится к тому, что по нажатию кнопки на форме WPF, я хочу открыть другую форму WPF, но не напрямую, а через запуск команды в классе!
Евгений, вам это нужно только для того, чтобы знать как это делается или действительно есть практическая цель сего действия?
Вообще так не делается.

Если знаете ее GUID, то можно так:
ИМХО, имеет смысл, только если это чья то чужая команда. Если ваша команда и есть ее исходники, то так делать не стоит.
По нажатию на кнопку формы нужно вызывать методы нужного класса, а не пытаться выполнить команду.
Название: Re: Запуск команды из формы WPF
Отправлено: Пашин Евгений от 19-11-2015, 10:41:55
Евгений, вам это нужно только для того, чтобы знать как это делается или действительно есть практическая цель сего действия?

Практическая цель.

ИМХО, имеет смысл, только если это чья то чужая команда. Если ваша команда и есть ее исходники, то так делать не стоит.
По нажатию на кнопку формы нужно вызывать методы нужного класса, а не пытаться выполнить команду.

Тут пока не понятно. Есть вероятность, что запуск чужой команды может потребоваться.
Мне, на данный момент, требуется запуск своей команды.

Вызвать метод нужного класса пробовал, на что получил от Ревита сообщение:

Программе Revit не удалось выполнить внешнюю команду.

код был таким:
Код - vb.net [Выбрать]
  1. Class MainWindow
  2.  
  3.     Private myCD As ExternalCommandData
  4.  
  5.     Public Sub New(ByVal commandData As ExternalCommandData)
  6.         MyBase.New()
  7.         InitializeComponent()
  8.         myCD = commandData
  9.     End Sub
  10.  
  11.     Private Sub Button_Click(sender As Object, e As RoutedEventArgs)
  12.         Dim mi As New WPF_Form_Show
  13.         mi.Make_It(myCD) ' пытался вызвать метод класса.
  14.     End Sub
  15. End Class
  16.  
  17.  
  18.  

Может у кого-нибудь есть ссылка на пример. Хоть на C#! Тогда я смогу определить, что я сделал не так.
Название: Re: Запуск команды из формы WPF
Отправлено: Пашин Евгений от 19-11-2015, 10:53:48
Антон Останин, спасибо за попытку! Работает, НО, когда форму закрываю )))

Наверное, это потому что:
myNewForm.ShowDialog()

Если сделать просто
myNewForm.Show()
то реакции вообще никакой, даже после закрытия формы...

Уже близко, но чуток непонятно!
Название: Re: Запуск команды из формы WPF
Отправлено: Виктор Чекалин от 19-11-2015, 10:59:52
Вызвать метод нужного класса пробовал, на что получил от Ревита сообщение:
Так нужно  в этом и разбираться, а не пытаться найти странное решение, путем
по нажатию кнопки запустилась команда, которую я создал в классе
:)

Смотрите, внешняя команда - это всего лишь входная точка.. возможность выполнить этот код (метод Execute) из пользовательского интерфейса Revit. Код самого метода может быть (и в большинстве случаев должен быть) очень короткий, например, открытие формы, или создание нового класса и выполнения метода. У вас судя по всему такой случай и есть.

Форму вы ведь все равно вызываете какой-то командой. Выходит, у вас есть команда, которая открывает форму, есть еще какая-то полезная команда, которую вы хотите вызывать по нажатию кнопки на форме. В таком случае, зачем вам вообще нужна вторая команда?

код был таким:
Без знания того, что содержится в методе Make_It сказать ничего нельзя. Также не ясно, как у вас открывается форма MainWindow. Возможно там тоже проблемы
Оберните вызов метода в try..catch увидите в чем ошибка. Возможно это из за того, что форма создана, но не отображена.

что я сделал не так
Пока что у вас неверный подход в принципе. Мой вывод, что вторая команда вам не нужна. Если нужна, то все что вам нужно делать в этой команде, вынесите в отдельный класс. Работайте с этим классом как при вызове команды, так и при нажатии кнопки на форме.
Попытался схематично это отобразить
Название: Re: Запуск команды из формы WPF
Отправлено: Виктор Чекалин от 19-11-2015, 11:00:49
myNewForm.Show()
Евгений, не делайте так.. Я уже говорил об этом.
Название: Re: Запуск команды из формы WPF
Отправлено: Пашин Евгений от 19-11-2015, 11:04:24
Евгений, не делайте так.. Я уже говорил об этом.

Я просто попробовал :)
Название: Re: Запуск команды из формы WPF
Отправлено: Пашин Евгений от 19-11-2015, 11:20:51
Итак, чтобы не быть не понятым, сразу раскрою причину моего вопроса: я в действительности пытаюсь понять, как подобный трюк работает в Revit Lookup, но с одно лишь разницей - в каждом новом окне будет свой уникальный набор команд или методов какой либо команды ( в Revit Lookup одна форма открывает другую форму, но всегда с новым содержимым).

Грубо говоря, мне нужно запихнуть в форму кнопки, которые запускают свои команды (у каждой кнопки своя команда). Также должна быть кнопка для открытия другой формы, в которой подразумевается, в дальнейшем, разместить кнопки, которые могли бы также иметь возможность запускать команды как и в предыдущей форме!!!

Как я понял из Ваших слов:
Мой вывод, что вторая команда вам не нужна. Если нужна, то все что вам нужно делать в этой команде, вынесите в отдельный класс. Работайте с этим классом как при вызове команды, так и при нажатии кнопки на форме.
мне тогда потребуется продублировать все команды, но запихнуть их в отдельные классы, с которыми и надо будет работать? Правильно понимаю?
Название: Re: Запуск команды из формы WPF
Отправлено: Пашин Евгений от 19-11-2015, 11:27:01
В таком случае, зачем вам вообще нужна вторая команда?

Ну, а если захочется сделать аналог палитры в AutoCAD, то почему бы и нет :)
Название: Re: Запуск команды из формы WPF
Отправлено: Виктор Чекалин от 19-11-2015, 11:33:27
Итак, чтобы не быть не понятым
Тогда и поясните сразу, что вы понимаете под командой?:) а то может у нас разные понятия:)
Название: Re: Запуск команды из формы WPF
Отправлено: Пашин Евгений от 19-11-2015, 11:35:42
Оберните вызов метода в try..catch увидите в чем ошибка. Возможно это из за того, что форма создана, но не отображена.

Попробовал и получил:

(https://adn-cis.org/forum/proxy.php?request=http%3A%2F%2Fs7.postimg.org%2Fjh6dwni9j%2Ferror.jpg&hash=12e23bfb7aec3ff0dbc06c64122f691f) (http://postimg.org/image/jh6dwni9j/)

Ошибка вроде так переводится: Невозможно изменить документ внешней команды, которая выполняется в режиме только для чтения, либо изменить документ, который временно отключен.
Могу ошибаться на счет перевода.
Название: Re: Запуск команды из формы WPF
Отправлено: Пашин Евгений от 19-11-2015, 11:38:36
Тогда и поясните сразу, что вы понимаете под командой? а то может у нас разные понятия:)
Ну, если языком пятиклассника, то звучит это так:
Команда - эта такая штуковина, которая выполняется (запускается) с помощью функции Execute и имеет свой уникальный guid. :)
Название: Re: Запуск команды из формы WPF
Отправлено: Антон Останин от 19-11-2015, 11:42:09
 
Код - C# [Выбрать]
  1. [TransactionAttribute(TransactionMode.Automatic)]
  2.     public class ExternalCommand : IExternalCommand
  3.     {
  4.  
  5.         public Result Execute(ExternalCommandData commandData, ref string message, Autodesk.Revit.DB.ElementSet elements)
  6.         {
  7.            return Result.Succeeded;
  8.         }
  9.  

Обратите внимание на атрибут класса команды.
Если хотите производить изменения то он должен быть
 
Код - C# [Выбрать]
  1.   [TransactionAttribute(TransactionMode.Automatic)]
  2.  
либо
 
Код - C# [Выбрать]
  1.   [TransactionAttribute(TransactionMode.Manual)]
  2.  
Название: Re: Запуск команды из формы WPF
Отправлено: Пашин Евгений от 19-11-2015, 11:43:43
[TransactionAttribute(TransactionMode.Manual)]

В моем случае Manual.

Обманул (неумышленно)!!! ))) Прошу прощения.
Название: Re: Запуск команды из формы WPF
Отправлено: Пашин Евгений от 19-11-2015, 11:46:34
О боже! Сработало!!!


Итак, как предложил Виктор Чекалин, всё получилось: создал метод внутри класса команды и запустил этот метод кнопкой на форме и сработало!!!
Но если бы Антон Останин не помог обнаружить проблему с аттрибутами, то идея бы была, как говорится, «коту подхвост». Вариант с guid тоже работает!

Как отметить решение, если ответа ДВА?
Название: Re: Запуск команды из формы WPF
Отправлено: Виктор Чекалин от 19-11-2015, 11:49:57
Команда - эта такая штуковина, которая выполняется (запускается) с помощью функции Execute и имеет свой уникальный guid.
Вот это и пытался уточнить. Это всего лишь возможность выполнить код из интерфейса Revit. Команда одна - возов формы. После этого команды не нужны. Идет простой обмен свойствами и вызов функций того или иного класса встроенными средствами фактически любого высокоуровнего языка программирования - с помощью конструктора или свойств класса.
С чего вы взяли что RevitLookup использует команды для каждой кнопки?:) Если вкратце, то у каждой формы есть конструктор, куда передается объект Revit. Получить этот объект мы можем как из выделенных объектов в модели (Snoop Current Selection), так и выбрав его в свойствах конкретного объекта в форме.

Вообще для RevitLookup есть исходники. https://github.com/jeremytammik/RevitLookup.git
Название: Re: Запуск команды из формы WPF
Отправлено: Пашин Евгений от 19-11-2015, 11:56:07
С чего вы взяли что RevitLookup использует команды для каждой кнопки?

Ну, предположил :)

Вот это и пытался уточнить. Это всего лишь возможность выполнить код из интерфейса Revit. Команда одна - возов формы. После этого команды не нужны. Идет простой обмен свойствами и вызов функций того или иного класса встроенными средствами фактически любого высокоуровнего языка программирования - с помощью конструктора или свойств класса.

Спасибо, буду знать!!!
Название: Re: Запуск команды из формы WPF
Отправлено: Виктор Чекалин от 19-11-2015, 11:58:38
Как отметить решение, если ответа ДВА?
Почему то ожидал, что вы просто пометите ответ Антона, как верный:)
Вообще на самом деле ни один из ответов не является ответом на исходный вопрос. Грубо говоря ответ это "В обработке события нажатия кнопки вызвать нужный метод" и все. А то что не получалось - это совсем по другой причине не имеющей отношения к вопросу.
Название: Re: Запуск команды из формы WPF
Отправлено: Пашин Евгений от 19-11-2015, 12:03:05
Надо предложить Александру Наумовичу идею о том, чтобы можно было пометить не только правильный ответ, но и сопутствующие ответы, которые явно указывают на решение или являются его дополнением :)
Название: Re: Запуск команды из формы WPF
Отправлено: Александр Ривилис от 24-11-2015, 10:17:57
Надо предложить Александру Наумовичу идею о том, чтобы можно было пометить не только правильный ответ, но и сопутствующие ответы, которые явно указывают на решение или являются его дополнением :)
Мод форума не позволяет это сделать, так что идея не проходит. Остаётся только плюсовать "сопутствующие ответы".
Название: Re: Запуск команды из формы WPF
Отправлено: Пашин Евгений от 24-11-2015, 11:18:21
Мод форума не позволяет это сделать, так что идея не проходит. Остаётся только плюсовать "сопутствующие ответы".

Ну и ничего страшного.
Название: Re: Запуск команды из формы WPF
Отправлено: Sergik от 23-01-2017, 16:45:45
Добрый вечер! Стоит типичная задача данной теме, загрузка семейства используя WPF. Вот мой код:
Код - C# [Выбрать]
  1. namespace WPFandRevitAPI
  2. {
  3.     [Transaction(TransactionMode.Manual)]
  4.     [Regeneration(RegenerationOption.Manual)]
  5.     public class Class1 : IExternalCommand
  6.     {
  7.         public Document doc = null;
  8.         public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
  9.         {
  10.             UIApplication Uiapp = commandData.Application;
  11.             doc = Uiapp.ActiveUIDocument.Document;
  12.             UserControl1 control = new UserControl1(this);
  13.             Window win = new Window();
  14.             win.ResizeMode = ResizeMode.NoResize;
  15.             win.Content = control;
  16.             win.Show();
  17.          }
  18. public void LoadFamily()
  19.         {
  20.             Transaction trans = new Transaction(doc);
  21.             trans.Start("LoadFamily");
  22.             doc.LoadFamily (@"c:\Users\home\Documents\Visual Studio 2015\Projects\WPFandRevitAPI\WPFandRevitAPI\bin\Debug\ЩРВ_IP31.rfa");
  23.             trans.Commit();
  24.         }
  25.  
Вот код логики:
Код - C# [Выбрать]
  1. namespace WPFandRevitAPI
  2. {
  3.     /// <summary>
  4.     /// Логика взаимодействия для UserControl1.xaml
  5.     /// </summary>
  6.     public partial class UserControl1 : UserControl
  7.     {
  8.         Class1 m_dataBuffer = null;
  9.         public UserControl1(Class1 dataBuffer)
  10.         {
  11.             m_dataBuffer = dataBuffer;
  12.             InitializeComponent();
  13.         }
  14.        private void ButtonLoad_Click(object sender, RoutedEventArgs e)
  15.         {
  16.             m_dataBuffer.LoadFamily();
  17.         }
  18. }
  19.  
Revit сразу вылетает при нажатии Button'a. В чем может быть проблема или как правильно загружать семейства?
Название: Re: Запуск команды из формы WPF
Отправлено: Антон Останин от 23-01-2017, 16:56:50
Sergik, здравствуйте. Чтобы Revit не падал, возьмите метод LoadFamily() в try catch. Заодно можете вывести сообщение об ошибке. Скорее всего это запуск транзакции не из API контекста, то есть из вашего контрола. Попробуйте сделать для проверки вызов метода из команды или запустить форму как win.ShowDialog().
Название: Re: Запуск команды из формы WPF
Отправлено: Sergik от 24-01-2017, 08:40:56
запустить форму как win.ShowDialog().
Правы на 100%, большое спасибо за решение!
Название: Re: Запуск команды из формы WPF
Отправлено: Sergik от 25-01-2017, 16:32:03
Скорее всего это запуск транзакции не из API контекста
Метод ShowDialog() действительно работает, но хотелось бы после загрузки семейства размещать его в проекте методом PromptForFamilyInstancePlacement() и при этом не закрывать форму каждый раз. Поэтому окно должно вызываться методом Show(), но тут Вы правы, запуск транзакции осуществляется не из API контекста. Выход предложил Jeremy Tammik в событии Idling, приведу даже код с SDK:
Код - C# [Выбрать]
  1. // Create a text note and update it once per second while Revit is idle
  2. TextNote textNote = null;
  3. String oldDateTime = null;
  4. public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
  5. {
  6.     UIApplication uiApp = new UIApplication(commandData.Application.Application);
  7.     Document doc = commandData.Application.ActiveUIDocument.Document;
  8.     using (Transaction t = new Transaction(doc, "Text Note Creation"))
  9.     {
  10.        t.Start();
  11.        oldDateTime = DateTime.Now.ToString();
  12.        ElementId defaultTextTypeId = doc.GetDefaultElementTypeId(ElementTypeGroup.TextNoteType);
  13.        textNote = TextNote.Create(doc, doc.ActiveView.Id, XYZ.Zero, oldDateTime, defaultTextTypeId);
  14.        t.Commit();
  15.     }
  16.     uiApp.Idling += new EventHandler<IdlingEventArgs>(idleUpdate);
  17.     return Result.Succeeded;
  18. }
  19. public void idleUpdate(object sender, IdlingEventArgs e)
  20. {
  21.     UIApplication uiApp = sender as UIApplication;
  22.     Document doc = uiApp.ActiveUIDocument.Document;
  23.     if (oldDateTime != DateTime.Now.ToString())
  24.     {
  25.         using (Transaction transaction = new Transaction(doc, "Text Note Update"))
  26.         {
  27.            transaction.Start();
  28.            textNote.Text = DateTime.Now.ToString();
  29.            transaction.Commit();
  30.         }
  31.         oldDateTime = DateTime.Now.ToString();
  32.     }
  33. }
Но я ума не приложу как прикрутить к этому событию обработчики моих WPF контролов. Из моего класса UserControl1 ничего не видно в Class1, ни обработчиков, ни контролов :( Помогите разобраться, пожалуйста
Название: Re: Запуск команды из формы WPF
Отправлено: Пашин Евгений от 26-01-2017, 06:53:01
Поэтому окно должно вызываться методом Show()

Давайте попробуем разобраться, для чего Вам нужно использовать метод Show()? Вы хотите иметь возможность сворачивать WPF форму/окно и дальше работать в Revit-e?

Я пытаюсь понять суть задачи (отметьте верно/неверно по каждому вопросу):
1. Вам нужно открывать WPF форму по нажатию кнопки на ленте?
2. Вам нужно, чтобы внутри WPF формы была кнопка, отвечающая за открытие определённого семейства (или любое другое действие)?
3. Вы хотите открывать другие семейства не закрывая WPF форму?
4. Вы хотите, чтобы WPF форма могла быть немодальной?

Пойму - помогу.
Название: Re: Запуск команды из формы WPF
Отправлено: Sergik от 26-01-2017, 09:45:59
Давайте попробуем разобраться, для чего Вам нужно использовать метод Show()? Вы хотите иметь возможность сворачивать WPF форму/окно и дальше работать в Revit-e?
Вы все верно поняли
Название: Re: Запуск команды из формы WPF
Отправлено: Пашин Евгений от 26-01-2017, 14:03:08
Sergik, если я правильно Вас понял, то результат должен быть как на видео?

Название: Re: Запуск команды из формы WPF
Отправлено: Sergik от 26-01-2017, 16:37:12
Хм... А получится ли у Вас загрузить семейство, и не закрывая формы (только свернуть) разместить в проекте, вот что надо. Вы использовали метод IdIing в примере?
Название: Re: Запуск команды из формы WPF
Отправлено: Пашин Евгений от 27-01-2017, 06:55:56
А получится ли у Вас загрузить семейство, и не закрывая формы (только свернуть) разместить в проекте

Вручную? Или автоматически? Я попробую, но не гарантирую, что успею сегодня это сделать.

Вы использовали метод IdIing в примере?

Нет.
Название: Re: Запуск команды из формы WPF
Отправлено: Sergik от 27-01-2017, 11:53:14
Вручную? Или автоматически? Я попробую, но не гарантирую, что успею сегодня это сделать.
Без разницы: можете автоматически, можете вручную попробовать через метод PromptForFamilyInstancePlacement(FamilySymbol)
Название: Re: Запуск команды из формы WPF
Отправлено: Антон Останин от 27-01-2017, 11:57:52
Sergik, я бы реализовал  IExternalEventHandler (https://knowledge.autodesk.com/search-result/caas/CloudHelp/cloudhelp/2016/ENU/Revit-API/files/GUID-0A0D656E-5C44-49E8-A891-6C29F88E35C0-htm.html). Здесь вы можете создавать свои события, в которых можно запускать транзакцию. Таким образом неважно открыто или закрыто ваше окно.
Название: Re: Запуск команды из формы WPF
Отправлено: Sergik от 27-01-2017, 14:27:24
Здесь вы можете создавать свои события, в которых можно запускать транзакцию. Таким образом неважно открыто или закрыто ваше окно.
А можно пример кода, спроецированный на мою задачу, если у Вас есть немного времени, конечно? Буду чрезмерно благодарен
Название: Re: Запуск команды из формы WPF
Отправлено: Sergik от 30-01-2017, 16:39:56
я бы реализовал IExternalEventHandler
Спасибо за подсказку, все получилось как задумывалось. Делюсь решением (Евгению отдельно спасибо за попытку). Код в команде:
Код - C# [Выбрать]
  1.                 UserControl1 control = new UserControl1();
  2.                 IExternalEventHandler loadfamily = new EventLoadFamilyInstance();
  3.                 ExternalEvent ExEventLoad = ExternalEvent.Create(loadfamily);
  4.                 control.eventLoad = ExEventLoad;
  5.  
Код в форме WPF:
Код - C# [Выбрать]
  1. public partial class UserControl1 : UserControl
  2.     {
  3.         public UserControl1()
  4.         {
  5.             InitializeComponent();
  6.             ...
  7.         }
  8.         public ExternalEvent eventLoad { get; set; }
  9.         public void ButtonLoad_Click(object sender, RoutedEventArgs e)
  10.         {
  11.             eventLoad.Raise();
  12.         }
  13.     }
  14. public class EventLoadFamilyInstance : IExternalEventHandler
  15.     {
  16.         public void Execute(UIApplication app)
  17.         {
  18.             UIDocument UIdoc = app.ActiveUIDocument;
  19.             Document doc = UIdoc.Document;
  20.             Transaction trans = new Transaction(doc);
  21.             trans.Start("Load");
  22.             doc.LoadFamilySymbol(string filename, string name);
  23.             trans.Commit();
  24.         }
  25.         public string GetName()
  26.         {
  27.             return "EventLoadFamilyInstance";
  28.         }
  29.     }
  30.  
Название: Re: Запуск команды из формы WPF
Отправлено: Владимир П от 05-05-2017, 12:32:49
Я пытаюсь понять суть задачи (отметьте верно/неверно по каждому вопросу):1. Вам нужно открывать WPF форму по нажатию кнопки на ленте?2. Вам нужно, чтобы внутри WPF формы была кнопка, отвечающая за открытие определённого семейства (или любое другое действие)?3. Вы хотите открывать другие семейства не закрывая WPF форму?4. Вы хотите, чтобы WPF форма могла быть немодальной?Пойму - помогу.
Приветствую, Евгений и всех кто в теме. А мне не поможете?
Пока интересует всего лишь первый пункт.
Т. е. у меня есть приложение, выполняющее некоторую графику в Ревит. Исходные данные задаются из кода, могу и Win форму добавить для ввода исходных данных (в других приложениях уже делал). Но хочется, чтобы это диалоговое окно было сделано в WPF. Вот как в Вашем видео. Т. е. это окно в WPF в принципе уже есть.
Интересует сама процедура как объединить эти две отдельные пока что части в единое приложение?
Если можно по-подробней и пошагово.
Название: Re: Запуск команды из формы WPF
Отправлено: Пашин Евгений от 05-05-2017, 14:17:43
Владимир П, добрый день.

Я пока не понял, какие именно две части Вы хотите сшить вместе. Как я понял, что Вы желаете видеть в одном плагине и формы WinForms и формы из WPF? Я правильно Вас понимаю? Если нет, то прошу поправить меня.

По созданию плагина под Revit с помощью WPF алгоритм будет следующим:
1. Создаём приложение WPF.
2. Затем меняем тип приложения на «WPF библиотека классов».
3. Затем добавляем изображение (48x48), которая будет играть роль кнопки закрытия формы WPF (назовите её для примера «close 48.png»).
4. Удаляем Application.xaml.
5. Подключаем ссылки на библиотеки: RevitAPI.dll, RevitAPIUI.dll, (убедитесь, что System.Data.DataSetExtensions,
System.Windows.Forms, System.Xaml тоже присутствуют)
6. У всех ссылок свойство «Копировать локально = False».
7. В модуле MainWindow.xaml поставьте код:

Код - XML [Выбрать]
  1. <Window x:Class="MainWindow"
  2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4. Title="MainWindow" Height="350" Width="525" Background="Transparent"
  5. AllowsTransparency="True" WindowStyle="None"
  6. WindowStartupLocation="CenterScreen" ResizeMode="CanResizeWithGrip" >
  7. <Grid>
  8. <Rectangle Fill="Transparent" Stroke="#FFFB2E00" StrokeThickness="3"/>
  9. <Rectangle Stroke="#FF002040" Opacity="0.6" StrokeMiterLimit="0" Margin="0,0,0,-5"
  10. StrokeThickness="0">
  11. <Rectangle.Effect>
  12. <DropShadowEffect x:Name="DS" BlurRadius="25" ShadowDepth="0" Color="Black" />
  13. </Rectangle.Effect>
  14. <Rectangle.Fill>
  15. <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
  16. <GradientStop Color="#FF05121F" Offset="0"/>
  17. <GradientStop Color="#FF2A74BD" Offset="1"/>
  18. </LinearGradientBrush>
  19. </Rectangle.Fill>
  20. </Rectangle>
  21. <Rectangle x:Name="TitleBar" Height="40" Stroke="#FF002040" VerticalAlignment="Top"
  22. StrokeThickness="3" Fill="#FF05121F" Opacity="0.7"/>
  23. <Button Content="Button" HorizontalAlignment="Left" Height="44" Margin="21,55,0,0"
  24. VerticalAlignment="Top" Width="232" Background="#FFF73901"
  25. BorderBrush="#FF052B91" BorderThickness="3" Click="Button_Click">
  26. <Button.Effect>
  27. <DropShadowEffect BlurRadius="15" Color="#FFA83104"/>
  28. </Button.Effect>
  29. </Button>
  30. <Image Height="28" Margin="0,7,7,0" VerticalAlignment="Top" HorizontalAlignment="Right"
  31. Width="28" Source="close 48.png"
  32. MouseDown="Image_MouseDown"/>
  33. </Grid>
  34. </Window>


8. В событии Image (кнопки, для которой Вы загрузили изображение), а именно MouseDown дважды кликаем в поле Image_MouseDown и откроется модуль MainWindow.xaml.vb, в котором мы всё напрочь удаляем и вставляем код:

Код - vb.net [Выбрать]
  1. Imports Autodesk.Revit
  2. Imports Autodesk.Revit.UI
  3. Imports Autodesk.Revit.DB
  4. Imports System
  5. Imports System.Windows.Forms
  6. Imports System.Text
  7. Class MainWindow
  8. Private myCD As ExternalCommandData
  9. Public Sub New(ByVal commandData As ExternalCommandData)
  10. MyBase.New()
  11. InitializeComponent()
  12. myCD = commandData
  13. End Sub
  14. Private Sub Button_Click(sender As Object, e As RoutedEventArgs)
  15. Dim App As Autodesk.Revit.UI.UIApplication = myCD.Application
  16. MsgBox(App.Application.VersionNumber)
  17. End Sub
  18. Private Sub TitleBar_MouseDown(sender As Object, e As MouseButtonEventArgs) Handles
  19. TitleBar.MouseDown
  20. Me.DragMove()
  21. End Sub
  22. Private Sub Image_MouseDown(sender As Object, e As MouseButtonEventArgs)
  23. Me.Close()
  24. End Sub
  25. End Class

9. Создаём класс WPF_Form_Show.vb

Код - vb.net [Выбрать]
  1. <Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.ReadOnly)> _
  2. Public Class WPF_Form_Show
  3. Implements Autodesk.Revit.UI.IExternalCommand
  4. Public Function Execute(ByVal commandData As Autodesk.Revit.UI.ExternalCommandData, _
  5. ByRef message As String, ByVal elements As Autodesk.Revit.DB.ElementSet) _
  6. As Autodesk.Revit.UI.Result Implements Autodesk.Revit.UI.IExternalCommand.Execute
  7. Dim myNewForm As New MainWindow(commandData)
  8. myNewForm.ShowDialog()
  9. Return Autodesk.Revit.UI.Result.Succeeded
  10. End Function
  11. End Class

10. Собираем сборку и копируем путь к сборке в буфер, нажав «Ctrl+C».
11. Переходим в папку «%Appdata%\Autodesk\Revit\Addins\2017» (у кого какая версия Revit-а)
12. Создаем в папке файл «Revit_WPF.addin»

Код - XML [Выбрать]
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <RevitAddIns>
  3. <AddIn Type="Command">
  4. <Name>Revit WPF Form</Name>
  5. <FullClassName>ИМЯ_ВАШЕГО_ПРОЕКТА_БИБЛИОТЕКИ.WPF_Form_Show</FullClassName>
  6. <Assembly>Полный путь к сборке</Assembly>
  7. <AddInId>94bc2dbd-560b-4669-9a92-dda4d11bdb6d</AddInId>
  8. <VendorId>Gallurgy</VendorId>
  9. <VendorDescription>ОАО Галургия, www.gallurgy.ru</VendorDescription>
  10. </AddIn>
  11. </RevitAddIns>

Результат Вам должен понравиться.





Если Вам потребуется иметь возможность использовать в одном плагине и формы WPF и WinForms, то тут алгоритм немного будет расширенным, но результат будет похож на это:

Название: Re: Запуск команды из формы WPF
Отправлено: Владимир П от 05-05-2017, 16:20:52
По созданию плагина под Revit с помощью WPF алгоритм будет следующим:
Евгений, огромное спасибо за столь быстрый и подробный ответ!
Воспроизвести это все также быстро у меня не получится, к сожалению. Но как только.. - так сразу сообщу о результатах.
Название: Re: Запуск команды из формы WPF
Отправлено: Владимир П от 08-05-2017, 11:03:15
Результат Вам должен понравиться.
Наконец-то, появилось время... Все получилось. Спасибо еще раз!
Теперь пробую переделать с VB на С# (с ходу не получилось).