WPF
Windows Presentation Foundation (WPF) — это решение для пользовательского интерфейса (UI) Windows, которое является частью .NET. Первоначально разработанный в 2006 году, он задумывался как преемник WinForms. Для получения дополнительной информации обратитесь к его официальной документации.
WPF позволяет создавать богатый и сложный UI. Он отделяет код от UI, используя XAML, язык на основе XML, разработанный Microsoft. cTrader Windows — это WPF-приложение, и все элементы UI, которые вы видите, работают на этом решении.
Использование WPF позволяет разрабатывать практически попиксельно точный многофункциональный UI. Однако у WPF крутая кривая обучения. Если вы хотите создать относительно простые элементы UI, вы можете использовать элементы управления графиком или WinForms.
Примечание
Алгоритмы, использующие WinForms или WPF, могут запускаться только на компьютерах с Windows.
Чтобы использовать WPF с сиБотами и индикаторами, измените компилятор cTrader со встроенного компилятора на компилятор .NET SDK.
Настройка вашего проекта
Аналогично WinForms, прежде чем вы сможете использовать WPF с вашими сиБотами и индикаторами, вам придется внести некоторые изменения в файл проекта вашего индикатора или сиБота. Поскольку WPF работает только в Windows, вам придется изменить целевую платформу вашего проекта индикатора или сиБота на вариант .NET для Windows.
Для этого откройте файл проекта в Visual Studio и замените его содержимое следующим:
1 2 3 4 5 6 7 8 9 10 | |
Мы добавили тег UseWpf и изменили значение TargetFramework на net6.0-windows.
Затем измените значение параметра класса AccessRights на FullAccess. Если это изменение не будет внесено, ваше расширение не будет иметь достаточных прав доступа для работы с WPF.
Пересоберите ваш проект после внесения вышеуказанных изменений.
Создание и отображение окна с использованием WPF
Процесс создания пользовательского окна аналогичен созданию пользовательской WinForm.
После того как вы настроили свой проект, щелкните по нему правой кнопкой мыши, выберите Add, а затем выберите Window (WPF)....

В открывшемся окне выберите опцию WPF window. Задайте имя окна MainWindow и нажмите кнопку Add. Новое окно WPF появится в обозревателе решений вашего проекта. У него будет два файла: файл .XAML и файл .cs, содержащий код бэкенда.
Откройте файл .XAML и скопируйте в него следующий код, чтобы изменить цвет фона на "SlateGray".
1 2 3 4 5 6 7 8 9 10 | |
Вставьте следующий код в основной исходный файл вашего индикатора:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | |
Когда вы добавляете новое окно WPF, оно будет использовать пространство имен вашего индикатора или сиБота (например, cAlgo). В файле .cs, содержащем код бэкенда окна, измените его на WPF_Test и убедитесь, что оно соответствует вашему оператору using в коде индикатора.
Пересоберите индикатор либо из Visual Studio, либо с помощью cTrader Algo.
После завершения процесса сборки создайте экземпляр индикатора. Вы должны увидеть свое пользовательское окно практически сразу после запуска.

Отобразите торговую панель
В этом примере мы создадим простую торговую панель с помощью WPF. Создайте новый сиБот и задайте ему имя WPF Trading Panel.
Откройте свой новый робот в Visual Studio и добавьте новый ресурс WPF, как описано выше. Задайте окну имя MainWindow.

После этого откройте файл .XAML окна и вставьте в него следующий код:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | |
Затем откройте файл бэкенда .cs и вставьте следующий код:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 | |
Теперь мы готовы запустить наше пользовательское окно с помощью нашего сиБота. Откройте исходный файл сиБота и вставьте код ниже:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | |
Пересоберите свой код с помощью Visual Studio и создайте экземпляр вашего сиБота. Запустите его, и должно появиться следующее окно.

В окне выберите инструмент из списка инструментов и нажмите Execute. Хотя наша торговая панель довольно проста, она работает так, как задумано. Вы можете использовать ее в качестве шаблона для создания сложных элементов управления WPF.
Код в файле .xaml.cs для нашего окна отвечает за отправку инструкций нашему сиБоту. При разработке кода бэкенда для ваших окон следуйте этим рекомендациям:
- Создайте сервис для управления взаимодействием с сиБотом или индикатором с помощью метода
BeginInvokeOnMainThread(). - Если вы создаете сложные элементы управления WPF, используйте MVVM, IoC и отделяйте компоненты бизнес-логики от пользовательского интерфейса (например, с помощью Prism)
Использование выделенного потока для UI
Окна WinForms и WPF должны работать внутри потока с пометкой STA, иначе они не будут работать. Для получения дополнительной информации обратитесь к официальной документации.
Вы не можете изменить свойство ApartmentState уже запущенного потока. Поскольку основной поток сиБота или индикатора не имеет пометки STA, вы должны использовать новый поток с пометкой STA для WinForms и WPF.
Получите доступ к членам API из потока пользовательского интерфейса
Как мы объяснили ранее, вам необходимо использовать отдельный выделенный поток для запуска ваших элементов управления WPF. Только код, выполняющийся в этом потоке, сможет получить доступ к элементам управления и свойствам окна.
То же самое верно для всех членов API алгоритмов. Поскольку API не является потокобезопасным, вы не можете получить доступ к членам API из потока пользовательского интерфейса. Вместо этого вам необходимо отправить работу с помощью метода BeginInvokeOnMainThread() в коде вашего индикатора или сиБота.
Это может создать сложности, если вы хотите обмениваться данными между вашим индикатором или сиБотом и окном WPF. Чтобы решить эту проблему, вы можете создать прокси-класс для управления взаимодействием между вашим сиБотом или индикатором и потоками, связанными с пользовательским интерфейсом.