Библиотеки элементов управления в дизайнере
Панель элементов дизайнера не ограничена контролами NetForms. На ней есть собственные контролы вашего проекта и
контролы любой библиотеки, на которую он ссылается, — пакета NuGet, .dll, другого проекта решения. На холсте они
настоящие: их конструкторы выполняются, они рисуют себя сами, а панель свойств и вкладка событий показывают их
собственные свойства и события.
Эта страница — практическое руководство. Как это устроено внутри — designer-control-libraries.md.
- Собственные контролы проекта
- Как подключить библиотеку
- Что говорит проверка
- Как убрать библиотеку и пересканировать
- Где это хранится:
.vscode/netforms.json - Попробовать: NetForms.ExtraControls
- Как написать библиотеку контролов для NetForms
- Безопасность: доверие к рабочей области
- Неполадки
Собственные контролы проекта
Ничего делать не нужно. Напишите контрол в проекте —
namespace Shop.Controls;
public class StarRating : Control
{
[DefaultValue(3), Category("Appearance"), Description("How many stars are lit.")]
public int Stars { get; set; } = 3;
protected override void OnPaint(PaintEventArgs e)
{
for (int i = 0; i < Stars; i++) e.Graphics.FillEllipse(Brushes.Gold, i * 20, 0, 18, 18);
}
}
— соберите проект (dotnet build, F5, NetForms: Rescan Toolbox или ↻ вверху панели элементов), и он появится в
группе Shop Components в начале панели, как в Visual Studio. В группе — все открытые контролы, пользовательские
контролы и компоненты проекта; формы не показываются (их проектируют, а не перетаскивают).
Дизайнер работает с последней успешной сборкой. Поменяйте контрол и соберите снова — открытые формы подхватят новую версию сами, без перезапуска. Контрол, написанный после последней сборки, до следующей показывается пунктирной заглушкой с именем типа; из формы при этом ничего не теряется.
Форма может наследовать форму проекта (public partial class OrderForm : BaseForm): на холсте видно то, что кладёт на
неё базовая форма, как в Visual Studio.
Своя группа для папки. Если контролов много, дайте папке отдельную группу: NetForms: Add Control Library… → Папка
этого проекта…, выберите Controls/Charts, назовите группу. Контролы пространства имён этой папки
(Shop.Controls.Charts) переедут из Shop Components в новую группу.
Как подключить библиотеку
NetForms: Add Control Library… — из палитры команд, кнопкой + Библиотека элементов… на панели элементов или из
контекстного меню .csproj в проводнике. Само ничего не ставится — ни при открытии формы, ни при перетаскивании:
библиотека попадает в проект только этой командой.
| Источник | Что вы делаете | Что меняется в проекте |
|---|---|---|
| Пакет NuGet… | Вводите название — поиск по nuget.org идёт по мере ввода, — затем выбираете версию (первой стоит последняя стабильная). | Пакет скачивается во временную папку и сначала проверяется. Затем dotnet add package. |
| Файл .dll… | Выбираете файл. | В .csproj добавляется <Reference> с <HintPath>. Файл вне проекта дизайнер предложит скопировать в libs/ (вместе с .pdb и .xml) — соглашайтесь, иначе на другой машине проект не соберётся. |
| .nupkg или папка-фид… | Выбираете .nupkg или папку с ними, затем пакет. |
Собственные и корпоративные пакеты. Папка становится источником пакетов в nuget.config проекта (он создаётся — вместе с nuget.org, — если его нет), дальше — как пакет NuGet. Дизайнер ещё раз спросит: пакет не с nuget.org. |
| Папка этого проекта… | Выбираете папку, называете группу. | Ничего: см. выше. |
| Другой проект… | Выбираете .csproj рабочей области (или «Обзор…»). |
dotnet add reference. Его контролы обновляются вслед за его сборками: пересоберите только тот проект — дизайнер возьмёт его свежий результат. |
| Пакет NuGet, уже подключённый к проекту… | Отмечаете пакеты, которые показывать. | Ничего: пакеты берутся из obj/project.assets.json (то, что разрешил dotnet restore), в том числе подключённые другими пакетами. |
После проверки дизайнер покажет найденные контролы и компоненты — с иконками из [ToolboxBitmap], — все с галочками.
Снимите галочки с того, что не нужно на панели. Затем проект собирается, и группа библиотеки появляется на панели
элементов всех открытых дизайнеров этого проекта.
Библиотеки, добавленные раньше в любом проекте, предлагаются первыми (Недавние): один выбор — и пакет или .dll уже в
новом проекте и на его панели.
Зависимости, версии, нативные части, конфликты — работа MSBuild и NuGet, ровно как при запуске приложения: дизайнер
загружает результат сборки проекта вместе с его .deps.json.
Что говорит проверка
Перед добавлением сборки библиотеки читаются без выполнения её кода (только метаданные):
| Библиотека | Дизайнер |
|---|---|
собрана под NetForms (ссылается на пакет NetForms) |
✅ добавляет |
| собрана под настоящий System.Windows.Forms | ⚠️ спрашивает: показать её контролы дизайнер может (фасад NetForms перенаправляет System.Windows.Forms), но проект с ней может не скомпилироваться — CS0012, строгое имя System.Windows.Forms, — и скорее всего не соберётся на Linux. См. Совместимость § сторонние пакеты. |
пакет, у которого нативные части только в runtimes/win-* |
⚠️ спрашивает: на Linux её контролы работать не будут |
пакет только для net*-windows |
⚠️ спрашивает: проекту нужен целевой фреймворк Windows |
собрана под .NET Framework (net48…), под .NET новее 10 или вовсе не сборка .NET |
❌ не добавляется, с объяснением |
У пакета проверяется та папка lib/, которую возьмёт проект net10.0: net10.0, иначе ближайшая более старая netX.0,
netcoreapp3.1, netstandard2.1, netstandard2.0.
Тип попадает на панель, как в Visual Studio: открытый, не абстрактный, не обобщённый компонент (IComponent) с открытым
конструктором без параметров, без [ToolboxItem(false)] и [DesignTimeVisible(false)] (на нём самом или на базовом
классе), и не форма. Компоненты без места на форме (как Timer) уходят в лоток.
Как убрать библиотеку и пересканировать
NetForms: Remove Control Library — выберите библиотеку, затем Только с панели элементов (ссылка в проекте
остаётся, он по-прежнему собирается с ней) или С панели элементов и из проекта (dotnet remove package /
dotnet remove reference или <Reference> удаляется из .csproj; .dll в libs/ остаётся на диске). Формы, где стоят
её контролы, сохраняют их — заглушками, которые хранят каждую строку своего кода.
NetForms: Rescan Toolbox (↻ на панели) собирает проект и заново читает его контролы и библиотеки. Дизайнер делает
это и сам — после каждой замеченной сборки и после изменения .csproj или .vscode/netforms.json.
Где это хранится: .vscode/netforms.json
Ссылки лежат там, где их читает MSBuild, — в .csproj. Что показывает панель элементов — в .vscode/netforms.json
рабочей папки, по проектам. Закоммитьте его — у коллег будет та же панель.
{
"projects": {
"src/Shop/Shop.csproj": {
"libraries": [
{
"id": "package:scottplot.winforms",
"name": "ScottPlot.WinForms",
"source": "package",
"package": "ScottPlot.WinForms",
"version": "5.0.47",
"assemblies": ["ScottPlot.WinForms.dll"],
"types": ["ScottPlot.WinForms.FormsPlot"]
},
{
"id": "folder:controls/charts",
"name": "Charts",
"source": "folder",
"path": "Controls/Charts",
"namespace": "Shop.Controls.Charts",
"assemblies": []
}
]
}
}
}
| Поле | |
|---|---|
name |
Группа на панели элементов. Можно менять. |
source |
package, dll, feed, folder, projectReference или projectPackage (пакет, уже подключённый к проекту). |
assemblies |
Файлы сборок библиотеки; ищутся в результате сборки проекта (пакет библиотеки классов, который туда не копируется, берётся из кэша NuGet). |
types |
Показываются только эти типы; без поля — всё, что предлагает библиотека. |
projectComponents: false |
(у проекта, рядом с libraries) скрывает автоматическую группу <Проект> Components. |
Библиотека, ссылка на которую пропала из .csproj (удалена руками, переключена ветка), просто не показывается — дизайнер
от этого не ломается.
Попробовать: NetForms.ExtraControls
NetForms.ExtraControls — библиотека контролов на nuget.org от самого проекта NetForms; на ней быстрее всего увидеть, как
пакет попадает на панель элементов:
- Откройте форму проекта NetForms в дизайнере.
- NetForms: Add Control Library… → NuGet package…, введите
NetForms.ExtraControls, выберите последнюю версию. - Проверка скажет ✅ собрана под NetForms и покажет шесть элементов со значками:
ToggleSwitch,RatingStars,CircularProgressBar,GradientPanel,ColorPickerButtonиCountdownTimer. Оставьте галочки. - Проект собирается, на панели элементов появляется группа NetForms.ExtraControls. Перетащите на форму
GradientPanel, в неё —ToggleSwitch;CountdownTimerуйдёт в лоток компонентов и запишется какnew CountdownTimer(components). - В окне свойств — их собственные категории и описания (Checked, OnColor, Duration…), на вкладке событий — их события (CheckedChanged, Finished…).
Из командной строки: dotnet add package NetForms.ExtraControls. Её исходники — src/NetForms.ExtraControls
в репозитории — полный пример для следующего раздела: атрибуты, значки, контейнер, компонент для лотка.
Как написать библиотеку контролов для NetForms
Библиотека контролов — это библиотека классов со ссылкой на NetForms:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="NetForms" Version="0.1.5" />
<Using Include="System.Drawing" />
<Using Include="System.Windows.Forms" />
</ItemGroup>
<ItemGroup>
<!-- Иконка панели элементов: 16×16, цвет левого нижнего пикселя — прозрачный. -->
<EmbeddedResource Include="Gauge.bmp" LogicalName="MyControls.Gauge.bmp" />
</ItemGroup>
</Project>
Дизайнер читает те же метаданные System.ComponentModel, что и Visual Studio:
| Атрибут | В дизайнере |
|---|---|
[ToolboxBitmap(typeof(Gauge), "Gauge.bmp")] |
Иконка на панели элементов (ресурс Namespace.Gauge.bmp находится и без атрибута). |
[ToolboxItem(false)], [DesignTimeVisible(false)] |
Не показывать на панели. |
[DefaultValue], ShouldSerializeX()/ResetX() |
Что пишется в *.Designer.cs; значение, отличное от умолчания, в панели свойств жирное. |
[Category], [Description], [Browsable(false)] |
Панель свойств. |
[DefaultEvent] |
Что подключает двойной щелчок по контролу. |
[TypeConverter] |
Как значение показывается и вводится в панели свойств. |
[DesignerSerializationVisibility(Content)] |
Коллекция или объект пишется своим содержимым. |
На холсте Site.DesignMode равен true, как на поверхности дизайна Visual Studio: таймеры, сеть и базы данных там лучше
не трогать. Собственные дизайнеры ([Designer], смарт-теги) и UITypeEditor пока не используются — панель свойств
редактирует значение текстом через его TypeConverter.
Упакуйте (dotnet pack) и подключите .nupkg через .nupkg или папка-фид… или опубликуйте на nuget.org.
Безопасность: доверие к рабочей области
Код библиотеки выполняется в процессе хоста дизайнера — её конструкторы, сеттеры свойств и OnPaint, — как и в Visual
Studio. Поэтому:
- В папке, которой VS Code не доверяет (ограниченный режим), панель показывает контролы проекта только по метаданным, серыми: их код не загружается, а Add Control Library недоступна. Доверьтесь папке — и они оживут.
- Пакет не с nuget.org (
.nupkg, локальный фид) перед добавлением подтверждается ещё раз. - Контрол, у которого бросает исключение конструктор или
OnPaint, рисуется красным крестом с текстом исключения (так WinForms рисует контрол, отрисовка которого упала). Форма всё равно открывается, и каждая строка кода этого контрола сохраняется. - Хост работает в отдельном процессе: что бы ни сделал контрол, VS Code вместе с ним не упадёт.
- Сборки загружаются из копии, поэтому следующий
dotnet buildне упрётся в занятую.dll.
Неполадки
| Что видно | Почему и что делать |
|---|---|
| На панели — Соберите проект, чтобы увидеть здесь его элементы управления | Проект ещё не собирался (нет bin/…/<Проект>.dll). Нажмите ↻ или выполните dotnet build. |
| Контрол на холсте — пунктирная рамка с именем типа | Его типа нет в последней сборке (написан позже или сборка упала), либо на библиотеку нет ссылки. Соберите проект; ошибки компилятора — в выводе NetForms. |
| Красный крест с исключением | Конструктор или OnPaint контрола бросил исключение на холсте. Оградите код, не нужный при проектировании: if (DesignMode) return; или Site?.DesignMode. |
| Элементы библиотеки серые | Ограниченный режим (доверьтесь папке) или загруженная сборка старше библиотеки (соберите снова). Подсказка при наведении скажет причину. |
| При добавлении — …нельзя использовать в дизайнере | См. Что говорит проверка: обычно библиотека только для .NET Framework. |
| Поиск по nuget.org ничего не находит | Поиск nuget.org недоступен (прокси, закрытая сеть): введите точный идентификатор пакета и нажмите Enter; версии берутся с api.nuget.org. В закрытой сети используйте локальный фид. |
| После добавления пакета WinForms проект не собирается | CS0012 про System.Windows.Forms: пакет собран под настоящий WinForms — см. Совместимость. Уберите его: Remove Control Library → С панели элементов и из проекта. |