Создание простого приложения Windows Forms: конвертер Цельсий → Фаренгейт
Важно: примеры приведены для Visual Studio 2019 Community с таргетом .NET Core 3.1. Подходы применимы и к более поздним версиям .NET с незначительными отличиями.
Кому это полезно
- Новичкам, изучающим C# и создание GUI в Windows.
- Разработчикам, которым нужно быстро прототипировать утилиту для рабочего стола.
- Тем, кто переходит с ручного редактирования к визуальному конструированию интерфейса.
Одно предложение о терминах
Windows Forms — фреймворк для создания десктоп-приложений с визуальным редактором форм и компонентами (виджетами).
Требования и подготовка
- Visual Studio 2019 Community (или более поздняя). Рекомендуется установить рабочую нагрузку «.NET desktop development».
- Таргет: .NET Core 3.1 (в статье) — также поддерживаются .NET 5/6/7 с похожим рабочим процессом.
- Базовые навыки C#: переменные, методы, обработчики событий.

Как создать проект Windows Forms в Visual Studio
- Откройте Visual Studio и выберите «Создать новый проект».
- В списке шаблонов найдите «Windows Form App» (Приложение Windows Forms) и выберите его, затем нажмите «Далее».

Примечание: если шаблон отсутствует, откройте Visual Studio Installer и добавьте рабочую нагрузку .NET desktop development.
- Укажите имя и расположение проекта, затем «Далее». Расположение — папка, где будут храниться файлы кода.

- На следующем экране оставьте по умолчанию .NET Core 3.1 (или выберите подходящую версию), нажмите «Создать».

- После создания проект откроется в среде Visual Studio — будет доступна форма Form1 и дизайнер.

Как добавлять элементы на форму (canvas)
Холст (canvas) — белая область редактора форм. Его можно изменять по размеру, перетаскивая маркеры на краях.
- Откройте меню «Вид» и выберите «Панель элементов» (Toolbox).

- Поставьте фиксацию панели элементов (pin), чтобы она оставалась видимой.
- Из панели элементов перетащите на форму: две TextBox, три Label и одну Button.

- Расположите метки и поля так, чтобы пользователь видел заголовок, поле ввода Цельсия, кнопку и поле вывода Фаренгейта.

- С выбранным элементом откройте окно «Свойства» (Properties) — обычно в правой части Visual Studio. Там можно изменить текст, имя, размер шрифта, режим только для чтения и прочие параметры.
- Измените текст и стиль заголовка: для label1 задайте Text = “Celsius to Fahrenheit” (можно локализовать на русский), размер шрифта — 22pt.

- Настройте остальные элементам следующие значения (таблица локализована):
| Элемент | Свойство | Новое значение |
|---|---|---|
| label2 | Text | Celsius |
| label3 | Text | Fahrenheit |
| button | Text | Calculate |
| Текстовое поле Fahrenheit | ReadOnly | True |
Совет: используйте понятные имена для элементов — это поможет в коде и при отладке.
Присвоение понятных имен элементам (Name)
Чтобы обращаться к элементам из кода, задайте их свойство Name:
| Элемент | Свойство | Новое имя |
|---|---|---|
| Текстовое поле Celsius | Name | celsiusTextBox |
| Текстовое поле Fahrenheit | Name | fahrenheitTextBox |
| Кнопка | Name | calculateButton |
Имена должны быть в стиле camelCase или PascalCase — используйте единый стиль в проекте.
Обработчики событий и код в Code-Behind
Windows Forms использует модель событий: действие в UI (например, клик) вызывает метод-обработчик в коде формы (Code-Behind).
- Двойной клик по кнопке Calculate автоматически создаст метод-обработчик в Form1.cs, например:
private void calculateButton_Click(object sender, EventArgs e)
{
// Здесь будет код обработки нажатия кнопки
}- Простейшая реализация, прочитав текст из поля, распарсив числа и записав результат в другое поле, выглядит так:
private void calculateButton_Click(object sender, EventArgs e)
{
// Получаем текст из текстового поля celsiusTextBox
double celsiusValue = Double.Parse(celsiusTextBox.Text);
// Преобразуем в Фаренгейт
double result = (celsiusValue * 9.0 / 5.0) + 32.0;
// Записываем результат в поле fahrenheitTextBox
fahrenheitTextBox.Text = result.ToString();
}Однако такой код ненадёжен: он бросит исключение, если пользователь введёт нечисловое значение. Ниже — более безопасная и локаль-устойчивая версия.
Надёжный парсинг с валидацией и обработкой ошибок
Рекомендуется использовать TryParse и учитывать локаль (десятичная точка или запятая). Также стоит отображать пользователю понятное сообщение об ошибке.
using System.Globalization;
using System.Windows.Forms;
private void calculateButton_Click(object sender, EventArgs e)
{
string input = celsiusTextBox.Text.Trim();
// Попробуем распарсить число с учётом текущей культуры пользователя
if (!double.TryParse(input, NumberStyles.Float | NumberStyles.AllowThousands, CultureInfo.CurrentCulture, out double celsiusValue))
{
MessageBox.Show("Пожалуйста, введите корректное числовое значение для Цельсия.", "Ошибка ввода", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
double result = (celsiusValue * 9.0 / 5.0) + 32.0;
// Форматируем результат с двумя знаками после запятой
fahrenheitTextBox.Text = result.ToString("N2", CultureInfo.CurrentCulture);
}Короткие пояснения:
- TryParse предотвращает исключения при нечисловом вводе.
- CultureInfo.CurrentCulture учитывает десятилитичный разделитель (‘,’ или ‘.’).
- Форматирование “N2” выводит две цифры после разделителя.
Валидация на уровне UI
- Для числового ввода можно использовать MaskedTextBox или явно обрабатывать событие KeyPress, отбрасывая недопустимые символы.
- Для критичных полей — добавьте подсказки (ToolTip) и описания доступности.
Как запускать и отлаживать программу
Запуск в Visual Studio
- Нажмите зелёную кнопку «Запуск» (Play) в панели инструментов.

- Введите значение в поле Celsius и нажмите Calculate — результат появится в поле Fahrenheit.

Проблемы с размытой графикой (DPI)
Если интерфейс выглядит размытым на мониторах с высоким разрешением, включите DPI-awareness через манифест приложения.
- Правой кнопкой мыши по проекту в Solution Explorer → Add → New Item → Application Manifest File.
- В app.manifest раскомментируйте или добавьте секцию внутри assembly:
true
true
- Перезапустите приложение из Visual Studio.
Примечание: для сложных сценариев масштабирования рассмотрите использование PerMonitorV2 DPI awareness в сочетании с тестированием на разных DPI.
Отладка (breakpoints)
- Откройте Form1.cs и кликните в область слева от номера строки, чтобы установить breakpoint (красная точка).
- Нажмите Calculate — выполнение приостановится в точке останова, и вы сможете просмотреть значения переменных в окне Locals/Watch.
- Продолжите выполнение зелёной кнопкой Continue или F5.

Запуск через EXE
Собранный исполняемый файл можно найти в папке проекта:
/bin/Debug/netcoreapp3.1/TemperatureConverter.exe Клик по EXE запустит приложение без Visual Studio.
Тестирование и критерии приёмки
Критерии приёмки для базового конвертера:
- Пользователь может ввести целое или дробное число (в локальной форме) и получить корректный результат.
- При вводе нечисловых символов появляется понятное сообщение об ошибке, приложение не падает.
- Поле Fahrenheit доступно только для чтения.
- UI не размывается на типичных DPI (100%, 150%, 200%).
Минимальные тест-кейсы:
- Ввод 0 → ожидаемый результат 32.00
- Ввод 100 → ожидаемый результат 212.00
- Ввод -40 → ожидаемый результат -40.00
- Ввод “abc” → показывает сообщение об ошибке, поле результата пустое
- Быстрое многократное нажатие кнопки не вызывает исключений
Лучшие практики и советы по архитектуре
- Отделяйте логику вычислений от UI: вынесите вычисления в отдельный класс/метод, чтобы их можно было юнит-тестировать.
- Используйте TryParse и локализованное форматирование.
- Для более сложных форм применяйте паттерн MVVM (при использовании WPF) либо отделяйте Presenter/Controller в WinForms.
- Не храните пользовательские данные в незащищённых файлах; используйте безопасное хранилище при необходимости.
Пример выделения логики в отдельный класс
public static class TemperatureConverter
{
public static double CelsiusToFahrenheit(double celsius) => (celsius * 9.0 / 5.0) + 32.0;
}
// В обработчике формы:
double result = TemperatureConverter.CelsiusToFahrenheit(celsiusValue);Это упрощает покрытие юнит-тестами и повторное использование.
Миграция и альтернативы: когда WinForms не подходит
Mermaid-диаграмма (поможет выбрать технологию):
flowchart TD
A[Требуется GUI для Windows] --> B{Простое десктоп-приложение?}
B -- Да --> C[WinForms]
B -- Нет --> D{Нужна богатая графика или MVVM?}
D -- Да --> E[WPF или Avalonia]
D -- Нет --> F{Кроссплатформенность?}
F -- Да --> G[MAUI или Electron]
F -- Нет --> CКогда стоит выбрать другое решение:
- Вам нужна кроссплатформенность (Mac/Linux) → рассматривайте MAUI, Avalonia или Electron.
- Необходима богатая векторная графика и сложные стили → WPF или современные фреймворки.
- Требуется мобильная поддержка → MAUI или Xamarin.
Контрольный список: роли и задачи
Разработчик:
- Создать форму и задать имена элементов.
- Реализовать обработчики с валидацией.
- Вынести вычисления в отдельный класс.
- Добавить логирование ошибок.
QA:
- Прогнать тест-кейсы на корректные/некорректные вводы.
- Проверить масштабирование и доступность.
- Протестировать сборку EXE и поведение без VS.
Системный администратор / деплой:
- Настроить установщик (MSI или MSIX) при необходимости.
- Проверить зависимости .NET на целевых машинах.
Безопасность и конфиденциальность
- Приложение, собирающее пользовательские данные, должно быть прозрачным о назначении данных и хранении.
- Не храните чувствительные данные в открытом виде в конфигурационных файлах.
- Для корпоративных сценариев добавьте аудит логов и управление доступом.
Локализация и доступность
- Текст в UI лучше вынести в ресурсы (.resx) для последующей локализации.
- Используйте инструмент локализации Visual Studio для добавления переводов.
- Для доступности: добавляйте описательные имена и подсказки (AccessibleName, AccessibleDescription) для элементов.
Отладочные советы и распространённые ошибки
- NullReferenceException при работе с элементом — убедитесь, что вы обращаетесь к элементам после InitializeComponent().
- FormatException при парсинге — переходите на TryParse.
- Работа с потоками: доступ к UI возможен только из UI-потока; используйте Invoke/BeginInvoke при работе с фоновыми задачами.
Примеры расширений и идей для развития приложения
- Добавить переключатель единиц (C ↔ F ↔ K).
- Сохранение истории вычислений в файл или локальную БД (SQLite).
- Добавить автодополнение и подсказки валидного ввода.
- Добавить модульные тесты для класса конвертации и интеграционные тесты для UI (с использованием инструментов автоматизации).
Краткая методология по созданию форм (4 шага)
- Проектирование: продумайте потоки ввода, ошибки и сценарии использования.
- Прототипирование: создайте форму и быстрые заглушки логики.
- Инкапсуляция: вынесите бизнес-логику в отдельные классы.
- Тестирование: юнит-тесты + ручное тестирование UI на нескольких DPI.
Глоссарий (1 строка каждый)
- WinForms: фреймворк для создания GUI в .NET с визуальным дизайнером форм.
- Code-Behind: файл с кодом, связанный с формой и её событиями.
- DPI-aware: приложение, корректно масштабирующееся на дисплеях с высокой плотностью пикселей.
Резюме
- WinForms остаётся быстрым способом создать простое десктоп-приложение для Windows.
- Используйте TryParse и CultureInfo для корректной обработки чисел и локализации.
- Отделяйте логику вычислений от UI ради тестируемости и поддержки.
Дополнительные ресурсы: официальная документация Microsoft по Windows Forms, руководства по локализации .resx и статьи про DPI-awareness.
Похожие материалы
Gmail и настольные клиенты: выбор и настройка
SketchUp бесплатно: как начать 3D‑моделирование
Как создать аккаунт PlayStation Network (PSN)
Почему iPhone и iPad нагреваются и как это исправить
Как искать жильё на Airbnb для отпуска