Гид по технологиям

Добавление тем в Windows Forms: Light, Nature и Dark

• 8 min read • Разработка • Обновлено 05 Dec 2025
Темы в Windows Forms: Light, Nature, Dark
Темы в Windows Forms: Light, Nature, Dark

Код на компьютере рядом с растениями

В современных десктопных приложениях часто нужна возможность менять тему интерфейса. Это улучшает удобство для пользователей и позволяет учитывать условия освещения и предпочтения. В Windows Forms можно реализовать темы, создавая управляемые наборы цветов и переключая их по нажатию кнопки.

В этой статье вы получите:

  • пошаговое руководство по созданию проекта и элементов управления;
  • готовые примеры кода для переключения тем;
  • рекомендации по хранению и восстановлению выбранной темы;
  • чек-листы для разработчиков, дизайнеров и тестировщиков;
  • сравнительный список альтернатив и советы по совместимости.

Что вам нужно заранее

  • Visual Studio (любой поддерживаемой версии для WinForms).
  • Базовые знания C# и работы с дизайнером форм.
  • Проект Windows Forms (Framework или .NET Core/5/6/7 — см. раздел совместимости).

Шаг 1. Создайте проект и расположите базовые элементы управления

  1. Создайте новый проект Windows Forms в Visual Studio.
  2. Добавьте на форму три больших кнопки (button1, button2, button3) и одну метку (label1).
  3. Отрегулируйте размеры и стиль через окно свойств.

В примере мы использовали следующие настройки через окно свойств:

КонтролСвойствоЗначение
button1Size580, 200
button1FlatStyleFlat
button1TextUsers
button2Size580, 100
button2FlatStyleFlat
button2TextAccounts
button3Size580, 100
button3FlatStyleFlat
button3TextPermissions
label1TextCopyright 2022

Поиск кнопки в панели инструментов

Кнопки на форме в WinForms

Метка на форме под кнопками

Окно свойств для кнопки в WinForms

Шаг 2. Добавьте кнопку настроек тем и список тем

Создайте дополнительную кнопку, которая будет показывать/скрывать выбор темы, и три кнопки для самих тем (Light, Nature, Dark).

  1. Добавьте кнопку настроек и задайте свойства:
СвойствоЗначение
NamebtnThemeSettings
FlatStyleFlat
Size200, 120
TextThemes

Окно свойств для кнопки в WinForms

  1. Добавьте три кнопки для тем и установите им начальные цвета и видимость в False:
КонтролСвойствоЗначение
btnLightThemeBackColorWhiteSmoke
btnLightThemeSize200, 80
btnLightThemeFlatStyleFlat
btnLightThemeTextLight
btnLightThemeVisibleFalse
btnNatureThemeBackColorDarkSeaGreen
btnNatureThemeSize200, 80
btnNatureThemeFlatStyleFlat
btnNatureThemeTextNature
btnNatureThemeVisibleFalse
btnDarkThemeBackColorDimGray
btnDarkThemeForeColorWhite
btnDarkThemeSize200, 80
btnDarkThemeFlatStyleFlat
btnDarkThemeTextDark
btnDarkThemeVisibleFalse

Окно свойств для кнопки в WinForms

  1. Создайте обработчик клика для кнопки настроек тем и переключайте видимость трех кнопок тем:
private void btnThemeSettings_Click(object sender, EventArgs e)
{
    btnNatureTheme.Visible = !btnNatureTheme.Visible;
    btnLightTheme.Visible = !btnLightTheme.Visible;
    btnDarkTheme.Visible = !btnDarkTheme.Visible;
}

Запустите приложение и убедитесь, что по умолчанию кнопки тем скрыты, а по нажатию на Themes они появляются и исчезают.

Play button in Visual Studio window

App at runtime with themes settings button

WinForms app at runtime showing available themes

Шаг 3. Управление наборами цветов (темами)

Лучше хранить цвета темы в одном месте — для этого подойдёт словарь Dictionary. Так вы сможете многократно применять наборы и централизованно обновлять палитру.

  1. Внутри класса Form объявите перечисление и словари:
enum ThemeColor
{
    Primary,
    Secondary,
    Tertiary,
    Text
}

Dictionary Light = new Dictionary();
Dictionary Nature = new Dictionary();
Dictionary Dark = new Dictionary();
  1. В конструкторе формы инициализируйте словари:
public Form1()
{
    InitializeComponent();

    // Add dictionaries here
    Light = new Dictionary() {
        { ThemeColor.Primary, Color.WhiteSmoke },
        { ThemeColor.Secondary, Color.Silver },
        { ThemeColor.Tertiary, Color.White },
        { ThemeColor.Text, Color.Black }
    };
    Nature = new Dictionary() {
        { ThemeColor.Primary, Color.DarkSeaGreen },
        { ThemeColor.Secondary, Color.AliceBlue },
        { ThemeColor.Tertiary, Color.Honeydew },
        { ThemeColor.Text, Color.Black }
    };
    Dark = new Dictionary() {
        { ThemeColor.Primary, Color.DimGray },
        { ThemeColor.Secondary, Color.DimGray },
        { ThemeColor.Tertiary, Color.Black },
        { ThemeColor.Text, Color.White }
    };

    // Apply default theme
    ChangeTheme(Light[ThemeColor.Primary], Light[ThemeColor.Secondary], Light[ThemeColor.Tertiary]);
    ChangeTextColor(Light[ThemeColor.Text]);
}

WinForms app at runtime with default theme applied

Шаг 4. Функции смены темы и цвета текста

Создайте функции, которые применяют цвета к элементам интерфейса. Это упрощает повторное использование и тестирование.

private void ChangeTheme(Color primaryColor, Color secondaryColor, Color tertiaryColor)
{
    // Change background color of buttons
    btnThemeSettings.BackColor = primaryColor;
    button1.BackColor = primaryColor;
    button2.BackColor = secondaryColor;
    button3.BackColor = secondaryColor;
    this.BackColor = tertiaryColor;
}

private void ChangeTextColor(Color textColor)
{
    // Change color of text
    button1.ForeColor = textColor;
    button2.ForeColor = textColor;
    button3.ForeColor = textColor;
    label1.ForeColor = textColor;
    btnThemeSettings.ForeColor = textColor;
}

И в обработчиках нажатия на кнопки тем используйте словари:

private void btnLightTheme_Click(object sender, EventArgs e)
{
    ChangeTheme(Light[ThemeColor.Primary], Light[ThemeColor.Secondary], Light[ThemeColor.Tertiary]);
    ChangeTextColor(Light[ThemeColor.Text]);
}

private void btnNatureTheme_Click(object sender, EventArgs e)
{
    ChangeTheme(Nature[ThemeColor.Primary], Nature[ThemeColor.Secondary], Nature[ThemeColor.Tertiary]);
    ChangeTextColor(Nature[ThemeColor.Text]);
}

private void btnDarkTheme_Click(object sender, EventArgs e)
{
    ChangeTheme(Dark[ThemeColor.Primary], Dark[ThemeColor.Secondary], Dark[ThemeColor.Tertiary]);
    ChangeTextColor(Dark[ThemeColor.Text]);
}

WinForms app at runtime showing Nature theme

WinForms app at runtime showing dark theme

Сохранение выбранной темы между запусками

Рекомендуемые варианты для хранения пользовательских настроек:

  • Properties.Settings (Application Settings) — простая кросс-платформенная опция внутри .NET;
  • JSON-файл в %AppData% (Environment.SpecialFolder.ApplicationData) — удобно версионировать и редактировать вручную;
  • реестр Windows — использовать осторожно; подходит для специфичных корпоративных сценариев.

Пример сохранения через Properties.Settings:

// В Settings.settings добавьте ключ CurrentTheme типа string
private void SaveTheme(string themeName)
{
    Properties.Settings.Default.CurrentTheme = themeName;
    Properties.Settings.Default.Save();
}

private void LoadTheme()
{
    var name = Properties.Settings.Default.CurrentTheme;
    if (name == "Nature") btnNatureTheme.PerformClick();
    else if (name == "Dark") btnDarkTheme.PerformClick();
    else btnLightTheme.PerformClick();
}

Вызовите LoadTheme() в конструкторе после InitializeComponent() и инициализации словарей.

Важно: не сохраняйте в настройках данные, требующие защиты (пароли, токены). Для них используйте безопасное хранилище.

Доступность и читаемость

  • Проверяйте контраст текста и фона (WCAG подходы). Для базовой проверки используйте соотношение контраста 4.5:1 для нормального текста.
  • Для тёмных тем используйте не чистый чёрный текст на ярких фонах — лучше слегка смещённые оттенки.
  • Обеспечьте переключение с клавиатуры (Tab/Enter) и доступность для экранных читалок (AccessibleName, AccessibleDescription).

Совет: делайте тестовые сценарии с реальными пользователями и автоматическими проверками контраста.

Альтернативные подходы и расширяемость

  1. Темы как набор ресурсов (ResourceDictionary): хранить цвета и стили в ресурсах и менять их программно.
  2. Создание классической темы через интерфейс ITheme с методами ApplyTo(Form form) — удобно для расширяемости и unit-тестов.
  3. Использование библиотек UI-стилей и фреймворков (например, MetroFramework, MaterialSkin) для более богатых тем и готовых компонентов.

Когда этот подход может не подойти:

  • если в приложении много кастомных отрисованных контролов, их придётся адаптировать вручную;
  • если нужна динамическая смена стилей для каждой части приложения отдельно — лучше внедрить централизованный менеджер тем.

Совместимость и миграция

Таблица совместимости по платформам .NET:

ПлатформаПримечания

| .NET Framework (4.6–4.8) | Полная поддержка WinForms; код из статьи работает без изменений. | .NET Core 3.1 | Поддержка WinForms доступна; возможны отличия в визуальном оформлении в зависимости от среды. | .NET 5/6/7 | Поддержка WinForms; рекомендуется тестировать поведение цветов и DPI.

При миграции из .NET Framework в .NET Core/.NET 5+ проверьте:

  • корректность ссылок на System.Drawing и Color;
  • поведение DPI и масштабирования;
  • дескрипторы конфигурации Properties.Settings (иногда надо мигрировать вручную).

Чек-листы по ролям

Разработчик:

  • создать словари тем и функции применения цветов;
  • обработать сохранение/загрузку выбранной темы;
  • обеспечить переключение с клавиатуры;
  • покрыть код простыми unit-тестами (при наличии абстракции ITheme).

Дизайнер:

  • подготовить наборы цветов с учётом контраста;
  • удостовериться, что иконки/изображения выглядят в каждой теме;
  • предоставить переменные для состояний hover/active/disabled.

QA:

  • проверить все темы на разных разрешениях и масштабах DPI;
  • проверить доступность клавиатурой и через скринридеры;
  • тестировать сохранение темы между запусками.

Тесты и критерии приёмки

Критерии приёмки:

  • по умолчанию приложение открывается в Light теме;
  • при выборе темы цвета всех основных элементов изменяются корректно;
  • выбранная тема сохраняется и восстанавливается при следующем запуске;
  • контраст текста не падает ниже приемлемого уровня для основных элементов.

Минимальные тестовые случаи:

  1. Запуск приложения — проверка Light по умолчанию.
  2. Нажатие Themes — кнопки тем отображаются.
  3. Выбор Nature — все цвета соответствуют словарю Nature.
  4. Выбор Dark — проверка белого текста на тёмном фоне.
  5. Перезапуск приложения — тема сохраняется.

Ментальные модели и эвристики при выборе цветов

  • Слойность: разделяйте Primary (главные элементы), Secondary (контекстные элементы), Tertiary (фон) и Text (типографика).
  • Контраст: текст должен быть читаемым на любом фоне; используйте инструменты для расчёта контраста.
  • Универсальность: выбирайте цвета, которые не ломают фирменную палитру при применении к иконкам и фотографиям.

Быстрый план внедрения (SOP)

  1. Спроектировать словари тем и перечисление ThemeColor.
  2. Добавить UI-кнопки для переключения и скрыть их по умолчанию.
  3. Реализовать ChangeTheme и ChangeTextColor.
  4. Добавить сохранение выбранной темы (Settings/JSON).
  5. Провести тесты на разных масштабах и с клавиатурой.
  6. Подготовить дизайн-проверку контраста.

Пример расширения: интерфейс ITheme и менеджер тем

Идея: абстрагировать тему через интерфейс, чтобы упростить тестирование и добавление новых тем.

public interface ITheme
{
    string Name { get; }
    Dictionary Palette { get; }
    void ApplyTo(Form form);
}

Менеджер тем может хранить список ITheme и обеспечивать уведомление о смене темы через событие.

Decision flowchart (Mermaid)

flowchart TD
    A[Нужна тема в приложении?] --> B{Требования}
    B -->|Простая| C[Использовать словари Color]
    B -->|Расширяемая| D[Реализовать ITheme и ThemeManager]
    B -->|Много кастомных контролов| E[Рефакторинг контролов и ручная адаптация]
    C --> F[Сохранение через Settings или JSON]
    D --> F
    E --> F

(Flowchart показывает простой выбор архитектуры для темы: словари для простых случаев, интерфейс для масштабируемых решений.)

Шаблон словаря тем (чек-лист для дизайнеров)

ПолеОписание
PrimaryЦвет главных кнопок/панелей
SecondaryЦвет вторичных кнопок/карточек
TertiaryФон формы
TextЦвет основного текста

Используйте этот шаблон для каждой темы и сохраняйте в одном месте (файл JSON, ресурс или класс).

Блок примечаний и ограничений

Important: Если ваше приложение содержит сторонние или кастомные контролы, убедитесь, что они поддерживают изменение BackColor и ForeColor. Не все сторонние компоненты корректно реагируют на программную смену цветов.

Note: В этой инструкции использованы встроенные цвета Visual Studio (Color.*). При желании замените их на свои HEX-значения через ColorTranslator.FromHtml(“#rrggbb”).

Краткое резюме

  • Реализуйте темы через перечисление ThemeColor и Dictionary для каждой темы.
  • Создайте функции ChangeTheme и ChangeTextColor для централизованного применения цветов.
  • Сохраняйте выбор пользователя через Settings или JSON, и обеспечьте доступность и адекватный контраст.
  • Для масштабируемости используйте интерфейсы и менеджеры тем.

1-line glossary:

  • ThemeColor — перечисление слоёв цвета: Primary, Secondary, Tertiary, Text.

Если нужно, я могу подготовить ZIP с примером проекта, JSON-шаблонами тем и unit-тестами для менеджера тем.

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Несколько аккаунтов Skype: Multi Skype Launcher
Программное обеспечение

Несколько аккаунтов Skype: Multi Skype Launcher

Журнал для работы: повысить продуктивность
Productivity

Журнал для работы: повысить продуктивность

Персональные звуки уведомлений на Android
Android.

Персональные звуки уведомлений на Android

Скачивание шоу Hulu для офлайн‑просмотра
Стриминг

Скачивание шоу Hulu для офлайн‑просмотра

Microsoft Start: персонализированная новостная лента
Новости

Microsoft Start: персонализированная новостная лента

Как изменить имя в Epic Games быстро
Гайды

Как изменить имя в Epic Games быстро