Как создать калькулятор на Windows Forms в Visual Studio
Кому и зачем это нужно
Эта статья полезна начинающим разработчикам, которые учатся создавать простые графические приложения на C#. Калькулятор — компактный проект, дающий опыт работы с UI (перетаскиванием элементов), обработчиками событий и базовой обработкой строк/исключений.
Важно: в примерах используется классическая Windows Forms (WinForms) в Visual Studio и фреймворк .NET, совместимый с DataTable.Compute(). Для других технологий (WPF, .NET MAUI) логика и работа с UI будут отличаться — см. раздел «Альтернативные подходы».
Ключевые преимущества проекта
- Быстро увидеть результат: UI + работающая бизнес-логика.
- Освоить привязку событий и работу с TextBox/Panel/Button.
- Практика преобразования строк выражений и обработки ошибок.
Оглавление
- Как добавить элементы интерфейса
- Добавление кнопок чисел и операторов
- Добавление области вывода результата
- Как добавить логику вычислений
- Обработка нажатий кнопок (button_Click)
- Вычисление результата (button_Equals_Click)
- Очистка (C и CE)
- Запуск приложения и тестирование
- Альтернативные подходы и когда они подходят
- Чек-листы по ролям (разработчик, дизайнер, тестировщик)
- Мини-методология реализации
- Критерии приёмки и тест-кейсы
- Шпаргалка: события, using и распространённые ошибки
- Краткий глоссарий и заключение
Как добавить элементы интерфейса
Начните с создания нового проекта Windows Forms в Visual Studio (New Project → Windows Forms App). Откройте форму в режиме дизайна: по умолчанию канвас открывается автоматически; если нет — откройте файл формы (.cs) и переключитесь на режим «Design».
Как добавить кнопки чисел и операторов
- Откройте дизайнер формы (Design view). Если у вас открыт код, выберите файл Form1.cs и в выпадающем списке переключитесь на проектирование.
- В Toolbox найдите элемент UI «Button» (Кнопка). Перетащите одну кнопку на канвас.
- Выделите кнопку и в окне свойств (Properties) задайте значения:
| Свойство | Новое значение |
|---|---|
| Name | button1 |
| Size | 120, 120 |
| Text | 1 |
- Добавьте ещё 19 кнопок, чтобы покрыть остальные цифры, операторы и функции.
- Для каждой кнопки в окне свойств измените Name и Text в соответствии с таблицей:
| Button | Свойство Name | Свойство Text |
|---|---|---|
| 2 | button2 | 2 |
| 3 | button3 | 3 |
| 4 | button4 | 4 |
| 5 | button5 | 5 |
| 6 | button6 | 6 |
| 7 | button7 | 7 |
| 8 | button8 | 8 |
| 9 | button9 | 9 |
| 0 | button0 | 0 |
| Addition | buttonAddition | + |
| Subtraction | buttonSubtraction | - |
| Multiplication | buttonMultiplication | X |
| Division | buttonDivision | ÷ |
| Decimal Point | buttonDecimal | . |
| Equals Sign | buttonEquals | = |
| Right Bracket | buttonRightBracket | ) |
| Left Bracket | buttonLeftBracket | ( |
| Clear | buttonClear | C |
| Clear Entry | buttonClearEntry | CE |
- Разместите кнопки на форме в привычном расположении калькулятора; сохраните одинаковый размер для всех кнопок для аккуратного вида.
- Для визуального выделения операторов можно изменить цвет кнопок через свойство BackColor. Выделите соответствующие кнопки и в окне свойств укажите цвет (например, Silver для операторов и Orange для C/CE).
Замечание: локализация текстов кнопок (например, заменять “+” на «плюс») не рекомендуется, если вы используете символы как часть выражений — оставляйте математические символы для удобства парсинга.
Как добавить область вывода результата
- Перетащите на форму элемент Panel (Панель).
- В окне свойств установите BackColor в White, при необходимости измените размер и позицию, чтобы панель выглядела как дисплей калькулятора.
- В Toolbox перетащите TextBox (Текстовое поле) на панель.
- Задайте свойства текстового поля:
| Свойство | Новое значение |
|---|---|
| name | textBoxOutput |
| BorderStyle | None |
| Text | 0 |
| TextAlign | Right |
| Enabled | False |
| BackColor | White |
- Разместите текстовое поле внутри панели так, чтобы оно служило строкой вывода.
Совет: можно сделать текст в textBoxOutput крупнее и выбрать моноширинный шрифт для лучшей читаемости длинных выражений.
Как добавить логику вычислений
Откройте файл формы (например, Form1.cs) и добавьте переменные и обработчики событий.
- В теле класса объявите строковую переменную currentCalculation, которая будет собирать выражение по мере нажатий:
public partial class Form1 : Form
{
private string currentCalculation = "";
public Form1()
{
InitializeComponent();
}
}- Создайте обработчик button_Click, который будет привязан ко всем цифровым и операторным кнопкам (кроме C, CE и =):
private void button_Click(object sender, EventArgs e)
{
// Добавляет текст нажатой кнопки в строку вычисления
currentCalculation += (sender as Button).Text;
// Отобразить текущее выражение пользователю
textBoxOutput.Text = currentCalculation;
}- Вернитесь в дизайнер, выделите каждую кнопку (исключая C, CE, =) и в окне Events (события) для Click укажите button_Click.
Примечание по безопасности: этот подход собирает строку выражения напрямую из текста кнопок. Если приложение будет принимать ввод извне, нужно дополнительно валидировать строку перед вычислением (см. раздел «Проверки и обработка ошибок»).
Как обработать нажатие знака равно
Создайте обработчик button_Equals_Click, который приведёт символы «X» и «÷» к символам, понятным для вычисления, и использует DataTable().Compute для получения значения:
private void button_Equals_Click(object sender, EventArgs e)
{
string formattedCalculation = currentCalculation.ToString().Replace("X", "*").ToString().Replace("÷", "/");
try
{
textBoxOutput.Text = new DataTable().Compute(formattedCalculation, null).ToString();
currentCalculation = textBoxOutput.Text;
}
catch (Exception ex)
{
// При ошибке восстанавливаем значение в 0 и очищаем строку вычисления
textBoxOutput.Text = "0";
currentCalculation = "";
}
}Обратите внимание: используемый символ деления в исходном HTML-примере был записан как ÷ — в коде WinForms используйте реальный символ ÷ в тексте кнопки или заменяйте строкой с этим символом.
Не забудьте добавить using System.Data; в начало файла, если пространства имён не подключены:
using System.Data;Затем в дизайнере выделите кнопку = и в Events → Click назначьте button_Equals_Click.
Проверки и обработка ошибок
- Обёртывайте Compute в try-catch, чтобы устойчиво обрабатывать неверные выражения (например, “123++7”). Далее — сбрасывайте вывод на “0” или показывайте удобное сообщение об ошибке.
- Подумайте о валидации: не допускайте двух операторов подряд, обеспечьте корректную расстановку скобок.
- Для более надёжного вычисления выражений можно использовать готовые парсеры выражений или написать собственный парсер (shunting-yard алгоритм), если требуются строже правила и контроль над приоритетом операций.
Как реализовать C (Clear) и CE (Clear Entry)
Создайте обработчик для кнопки Clear, который полностью сбрасывает текущее выражение и поле вывода:
private void button_Clear_Click(object sender, EventArgs e)
{
// Сброс выражения и поля вывода
textBoxOutput.Text = "0";
currentCalculation = "";
}Назначьте этот обработчик для кнопки C через Events → Click.
Для Clear Entry удалите последний введённый символ из строки вычисления:
private void button_ClearEntry_Click(object sender, EventArgs e)
{
if (currentCalculation.Length > 0)
{
currentCalculation = currentCalculation.Remove(currentCalculation.Length - 1, 1);
}
textBoxOutput.Text = currentCalculation;
}Назначьте этот обработчик для CE.
Замечание: можно расширить CE, чтобы она удаляла до предыдущего оператора (удалять последнее число целиком) — это зависит от ожидаемого поведения пользователей.
Как запустить приложение и проверить работу
- Нажмите зелёную кнопку “Play” (Запуск) в Visual Studio.
- По нажатию кнопок калькулятора выражение будет отображаться в белой области сверху; при нажатии = поле заменится на результат. C и CE работают как указано.
Тестирование простых случаев: 2+2, 12/4, (3+5)*2. Проверьте пограничные случаи: деление на ноль, пустое выражение, последовательность операторов.
Альтернативные подходы и когда они подходят
- WPF: если нужна более гибкая привязка данных (data binding), векторная графика и современные UI-паттерны — выбирайте WPF.
- .NET MAUI / Xamarin: если вы планируете кроссплатформенный GUI (Windows + macOS + мобильные), эти фреймворки лучше.
- Собственный парсер выражений: когда требуется точный контроль над синтаксисом и обработкой ошибок (например, поддержка функций sin/cos, степеней), реализуйте парсер на основе алгоритма Dijkstra (shunting-yard) и вычислитель на основе стеков.
Когда не использовать Compute(): DataTable.Compute удобна для простых проектов и прототипов, но она менее контролируема и потенциально более уязвима при приёме внешнего ввода. Для продакшн-систем рассмотрите безопасные парсеры выражений.
Чек-листы по ролям
Для разработчика
- Создать Windows Forms проект.
- Добавить кнопки и текстовое поле вывода.
- Реализовать button_Click для основных кнопок.
- Реализовать button_Equals_Click с обработкой ошибок.
- Подключить using System.Data; при необходимости.
- Написать unit/интеграционные тесты для вычислений.
Для дизайнера UI
- Разработать макет кнопок и дисплея.
- Убедиться, что шрифты и размеры читаемы.
- Выделить операторы цветом для удобства.
- Проверить доступность (контраст, фокус клавиатуры).
Для тестировщика
- Проверить базовые вычисления и скобки.
- Проверить обработку неправильных выражений.
- Проверить работу C и CE.
- Проверить поведение при копировании/вставке (если реализовано).
Мини-методология реализации (быстрая дорожная карта)
- Скелет: создать проект и форму.
- UI: разместить панели, TextBox, все кнопки.
- Логика: currentCalculation + button_Click.
- Результат: button_Equals_Click с DataTable.Compute.
- Очистка: implement C и CE.
- Тестирование: ручные тесты и набор автоматических проверок.
- Рефакторинг: вынести парсер/вычислитель при увеличении требований.
Критерии приёмки
- Интерфейс отображается корректно в режиме выполнения.
- Ввод чисел и операторов обновляет дисплей.
- Нажатие = вычисляет корректный результат для базовых выражений.
- Неверные выражения обрабатываются без краха (показывается 0 или сообщение).
- C полностью очищает состояние; CE удаляет последний символ/ввод.
Тест-кейсы и критерии приёмки (примеры)
Простые операции: 2 + 3 = 5.
Критерий приёмки: результат 5 отображается.Сложение с десятичными: 2.5 + 0.75 = 3.25.
Критерий приёмки: корректное отображение десятичной точки.Скобки: (3 + 5) * 2 = 16.
Критерий приёмки: соблюдается приоритет скобок.Повторные операторы: ввод «123++7» → нажать =.
Критерий приёмки: приложение не падает, дисплей показывает 0.Деление на ноль: 7 ÷ 0.
Критерий приёмки: обработка исключения без падения (0 или сообщение об ошибке).CE: в выражении 123+45 нажать CE → результат должен показать 123+4 (если CE удаляет один символ) или 123+ (если удалять целое число — в зависимости от реализации).
Критерий приёмки: поведение соответствует спецификации продукта.
Шпаргалка: события, using и распространённые ошибки
- Событие Click для группы кнопок: выделите несколько кнопок и в окне Events укажите один обработчик (button_Click) — это связывает все выбранные кнопки с одним методом.
- Подключение пространства имён для Compute: using System.Data;
- Частые ошибки: неправильное представление символа деления (HTML-сущности ÷ не работают в тексте кнопки), отсутствие проверки пустой строки перед Compute, не назначенные обработчики для кнопок.
Короткий фрагмент кода назначения обработчика программно (если нужно назначать в коде):
// В конструкторе формы после InitializeComponent()
button1.Click += button_Click;
button2.Click += button_Click;
// и т.д.Решение для более сложных выражений (шпаргалка)
Если вы планируете поддерживать функции (sin, cos, pow), переменные или безопасный ввод, замените DataTable.Compute на один из следующих подходов:
- Реализовать парсер выражений (shunting-yard) и вычислитель на стеке.
- Использовать стороннюю библиотеку парсинга выражений (например, NCalc или аналог), проверив её лицензию.
1‑строчный глоссарий
- Windows Forms (WinForms) — фреймворк для создания настольных GUI-приложений на .NET.
- Toolbox — панель компонентов в Visual Studio для перетаскивания элементов UI.
- Panel — контейнер для группировки элементов интерфейса.
- TextBox — элемент ввода/вывода текста.
- DataTable.Compute — удобный метод .NET для вычисления строковых арифметических выражений.
Когда эта реализация не подойдёт (контр-примеры)
- Нужна поддержка синусов/логарифмов/пользовательских функций — DataTable.Compute не покрывает это.
- Требуется строгий контроль над обработкой числовых погрешностей или специфические правила парсинга — лучше свой парсер.
- Приложение должно быть кроссплатформенным (мобильные клиенты) — используйте MAUI/Flutter/React Native.
Безопасность и приватность (замечания)
Этот калькулятор локальный и не отправляет данные по сети. Если добавляете сохранение истории или синхронизацию, учитывайте местные требования по хранению данных и оповещайте пользователя.
Быстрые советы по локализации для русскоязычных пользователей
- Символы операций оставьте как символы (+, -, ÷, X) — они привычны и удобны для парсинга.
- Подумайте о форматировании чисел: разделитель дробной части в России — запятая (“,”) по привычке пользователя, но в программировании часто используется точка (“.”) — решите, поддерживаете ли ввод с запятой и заменяйте её на точку перед вычислением.
Пример замены запятой на точку перед вычислением:
currentCalculation = currentCalculation.Replace(',', '.');Заключение
Калькулятор — отличный обучающий проект: он показывает, как работаю UI-элементы WinForms, связываются события и выполняются простые вычисления. Для быстрого прототипа DataTable.Compute подходит прекрасно, но для расширенной функциональности стоит использовать или написать надёжный парсер выражений.
Если вы хотите, я могу:
- Подготовить проект-скелет (.zip) с готовой формой и обработчиками;
- Показать, как реализовать парсер выражений на основе алгоритма shunting-yard;
- Написать серию unit-тестов для вычислительной логики.
Похожие материалы
RDP: полный гид по настройке и безопасности
Android как клавиатура и трекпад для Windows
Советы и приёмы для работы с PDF
Calibration в Lightroom Classic: как и когда использовать
Отключить Siri Suggestions на iPhone