Как создать окно ввода в Windows Forms

Модальные диалоги часто используются в десктопных приложениях, когда нужно запросить у пользователя небольшое количество данных. В Windows Forms вы можете создать такое окно вручную: программно создать форму, добавить метки, текстовые поля и кнопки “ОК”/“Отмена” и получить введённое значение.
В этой статье вы найдёте:
- полную реализацию InputBox на C#;
- пример использования в обработчике кнопки;
- рекомендации по валидации, доступности и локализации;
- тесты, критерии приёмки и альтернативные подходы.
Что такое InputBox — одно предложение
InputBox — это модальное окно, которое запрашивает у пользователя текст и возвращает результат вместе с DialogResult (OK/Cancel).
Структура статьи
- Как сгенерировать обработчик клика для открытия диалога
- Полная реализация InputBox (код)
- Пример использования в обработчике
- Советы по дизайну, доступности и локализации
- Когда такой подход не подходит и альтернативы
- Тесты, критерии приёмки и чек‑листы
Как создать on-click функцию для открытия окна ввода
Диалог не должен отображаться постоянно. Его стоит показывать при определённом действии — например, при клике на кнопку.
- Создайте новое приложение Windows Forms в Visual Studio.
- В панели Toolbox найдите элемент Button.
- Перетащите кнопку на форму.
- В окне свойств задайте значения:
| Property Name | New Value | | — | — | | Name | dialogButton | | Size | 400, 100 | | Text | Open Input Dialog | - Перетащите на форму Label и разместите справа от кнопки.
- В свойствах метки задайте:
| Property Name | New Value | | — | — | | Name | labelResponseInput | | Visible | False | - Дважды щёлкните по кнопке Open Input Dialog — Visual Studio сгенерирует обработчик клика:
private void dialogButton_Click(object sender, EventArgs e)
{
// Здесь будет вызов InputBox и обработка результата
}Важно: генерируйте обработчики через дизайнер, чтобы привязки событий и имена элементов соответствовали коду.
Полная реализация InputBox (готовый, компилируемый пример)
Ниже — реалистичная и практичная реализация InputBox в стиле Windows Forms. Она учитывает предзаполнение значения, стандартное поведение клавиш Enter/Escape и возвращает DialogResult.
public static DialogResult InputBox(string title, string promptText, ref string value)
{
// Создаём форму и контролы
Form form = new Form();
Label label = new Label();
TextBox textBox = new TextBox();
Button buttonOk = new Button();
Button buttonCancel = new Button();
// Заголовок и текст
form.Text = title;
label.Text = promptText;
// Текст кнопок и результаты
buttonOk.Text = "OK";
buttonCancel.Text = "Cancel";
buttonOk.DialogResult = DialogResult.OK;
buttonCancel.DialogResult = DialogResult.Cancel;
// Предзаполнить текстовое поле
textBox.Text = value ?? string.Empty;
// Размеры и расположение
label.SetBounds(12, 12, 460, 20);
textBox.SetBounds(12, 40, 460, 20);
buttonOk.SetBounds(200, 80, 120, 36);
buttonCancel.SetBounds(328, 80, 120, 36);
// Свойства формы
label.AutoSize = true;
form.ClientSize = new Size(486, 132);
form.FormBorderStyle = FormBorderStyle.FixedDialog;
form.StartPosition = FormStartPosition.CenterParent;
form.MinimizeBox = false;
form.MaximizeBox = false;
form.ShowIcon = false;
form.ShowInTaskbar = false;
// Добавляем элементы
form.Controls.AddRange(new Control[] { label, textBox, buttonOk, buttonCancel });
// Кнопки по умолчанию
form.AcceptButton = buttonOk;
form.CancelButton = buttonCancel;
// Улучшаем доступность
label.TabIndex = 0;
textBox.TabIndex = 1;
buttonOk.TabIndex = 2;
buttonCancel.TabIndex = 3;
label.AccessibleName = "promptLabel";
textBox.AccessibleName = "inputField";
// Показываем диалог модально относительно родительской формы
DialogResult dialogResult = form.ShowDialog();
// Возвращаем значение и результат
value = textBox.Text;
return dialogResult;
}Примечание: здесь используется StartPosition = CenterParent. Если вы вызываете InputBox из основной формы, передавайте её как родителя: form.ShowDialog(ownerForm). В простом варианте ShowDialog() центрируется относительно экрана.
Как вызвать InputBox из обработчика клика
Внутри dialogButton_Click создайте переменную для результата и вызовите InputBox:
private void dialogButton_Click(object sender, EventArgs e)
{
string value = "";
if (InputBox("Dialog Box", "What is your name?", ref value) == DialogResult.OK)
{
labelResponseInput.Visible = true;
labelResponseInput.Text = "Your name: " + value;
}
}Этот код показывает диалог и, если пользователь нажал OK, отображает результат в метке на форме.
Советы по дизайну и пользовательскому опыту
- Держите текст подсказки (promptText) коротким и понятным. Одной фразы обычно достаточно.
- Используйте предзаполнение, если есть ожидаемое значение.
- Не делайте диалог слишком большим: он должен быть минимален по содержимому.
- Если ввод чувствителен (пароль), используйте TextBox.PasswordChar или TextBox.UseSystemPasswordChar = true.
Важно: модальные окна блокируют UI-поток, пока пользователь не закроет диалог. Для длительных операций используйте неблокирующие подходы.
Доступность и локализация
- Задайте AccessibleName и AccessibleDescription для контролов.
- Убедитесь, что порядок вкладок (TabIndex) логичен.
- Локализуйте строки (заголовки, подсказки, текст кнопок) через ресурсы (.resx).
- Для прав-to-left языков учитывайте RightToLeft свойство.
Валидация ввода
Добавьте проверку введённого текста перед закрытием формы. Простой способ — обработчик события для кнопки OK:
buttonOk.Click += (sender, e) =>
{
if (string.IsNullOrWhiteSpace(textBox.Text))
{
MessageBox.Show("Пожалуйста, введите значение.", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Warning);
// не закрывать форму
}
else
{
form.DialogResult = DialogResult.OK;
form.Close();
}
};Если проверка сложнее, рассмотрите использование ErrorProvider для показа ошибок рядом с полем.
Когда этот подход не подходит (примеры)
- Если приложение должно оставаться отзывчивым при вводе (например, длительные сетевые проверки) — модальный диалог будет блокировать UI.
- Когда требуется сложный ввод (много полей, много этапов) — лучше отдельная форма/страница или мастер (wizard).
- Для сервисов и фонов задач — десктопный диалог невозможен.
Альтернативные подходы
- Создать отдельную Form с дизайнером и использовать её как диалог (удобно, если диалог сложный).
- Использовать WPF для более гибкого UI и привязок данных.
- Воспользоваться Microsoft.VisualBasic.Interaction.InputBox для простых сценариев (есть в .NET при подключении пакета Microsoft.VisualBasic).
- Использовать кастомный UserControl, показываемый внутри панели приложения вместо модального окна.
Мини‑методология: как быстро спроектировать диалог ввода
- Определите цель диалога и минимальный набор полей.
- Продумайте валидацию и поведение клавиш Enter/Escape.
- Решите, будет ли диалог модальным или нет.
- Подумайте об адаптации для разных размеров экранов и DPI.
- Напишите тесты и критерии приёмки (см. ниже).
Критерии приёмки
- Диалог открывается при клике на кнопку и центрируется относительно формы.
- Введённый текст возвращается через параметр ref и DialogResult при OK.
- Нажатие Escape эквивалентно нажатию “Отмена” и не сохраняет значение.
- Клавиша Enter подтверждает ввод при фокусе в поле ввода.
- Порядок вкладок корректен, контролы доступны экранным читалкам.
Тесты и сценарии приёма (примеры)
- Показать диалог и нажать OK без ввода → ожидается предупреждение (если поле обязательное).
- Ввести текст и нажать OK → ожидается DialogResult.OK и сохранение текста.
- Открыть диалог и нажать Cancel или Escape → ожидается DialogResult.Cancel и отсутствие изменений.
- Проверить TabIndex: переходы по клавише Tab логичны.
- Проверить локализацию: тексты меняются при переключении ресурсов.
Чек‑лист ролей
- Разработчик: реализовать InputBox, учесть TabIndex, AccessibleName, обработку Enter/Escape.
- QA: протестировать сценарии из раздела тестов и проверить на нестандартных DPI.
- UX: проверить читаемость текста, расположение кнопок и смысл подсказки.
Безопасность и приватность
- Не храните чувствительные данные в простом тексте. Для паролей используйте защищённые поля и не логируйте ввод.
- Если передаёте данные через сеть, шифруйте канал и применяйте безопасное хранение.
Примеры ошибок и как их избежать
- Ошибка: вызов InputBox из фонового (не UI) потока → исключение.
Решение: вызывать через Invoke/BeginInvoke или из UI-потока. - Ошибка: длинный текст обрезается → проверяйте размеры и используйте AutoSize или прокрутку.
Краткое сравнение подходов
- Программная сборка формы (как в статье): гибко, удобно для простых диалогов.
- Предсозданная форма (Designer): удобна для сложных форм и поддерживается дизайнером VS.
- WPF: лучше для сложных интерфейсов и современных приложений.
Быстрый шаблон для документации функции
- Название: InputBox
- Вход: title (string), promptText (string), ref value (string)
- Выход: DialogResult (OK/Cancel), value обновлён
- Побочные эффекты: показывает модальное окно, блокирует UI-поток
Decision flow (какой подход выбрать)
flowchart TD
A[Нужен простой ввод?] -->|Да| B[InputBox 'простая форма']
A -->|Нет, сложный ввод| C[Отдельная форма/мастер]
C --> D{Нужна гибкая привязка данных?}
D -->|Да| E[WPF]
D -->|Нет| F[WinForms Designer]Примеры локализации и ресурсов
- Выносите строки в .resx: “DialogTitle”, “PromptName”, “ButtonOk”, “ButtonCancel”.
- При переключении культуры подгружайте соответствующий ресурс.
Завершение и рекомендации
InputBox — простая и удобная техника для запросов небольшого объёма данных в WinForms. Для простых случаев достаточно программной сборки формы, предоставлённой выше. Если диалог усложняется, переходите на дизайнер или WPF.
Важно: тестируйте диалоги на разных масштабах экрана и учитывайте требования доступности. Используйте локализацию и не храните чувствительные данные в открытом виде.
Короткое резюме:
- Реализуйте InputBox как отдельную функцию, возвращающую DialogResult и изменяющую ref-параметр;
- Обработайте Enter/Escape, табуляцию и accessibility;
- Добавьте валидацию и тесты;
- Выбирайте альтернативы для сложных сценариев.
Примечания
- Для многоплатформенных сценариев рассмотрите создание абстракции диалога, чтобы при миграции на WPF или другую технологию минимально менять код.
- Для быстрых прототипов можно задействовать Microsoft.VisualBasic.Interaction.InputBox, но он ограничен по кастомизации.
Похожие материалы
Преобразовать Fire TV Stick в ТВ-приставку
AR View Amazon: примерить мебель в вашей комнате
Как убрать ошибку access control entry is corrupt
Умный навесной замок: установка и настройка
Как вызвать экранную клавиатуру Steam Deck