Диалоговое окно (dialog box) — это вспомогательное окно программы, через которое она сообщает что-то пользователю или запрашивает у него решение: подтвердить удаление, выбрать файл, ввести имя. Главное свойство диалога — модальность: блокирует ли он работу с основным окном, пока его не закроют.
Содержание
- Окно, диалоговое окно и окно сообщения: в чем разница
- Модальные и немодальные диалоговые окна
- Стандартные диалоги Windows
- Кнопки ОК, Отмена и Применить
- Пример: окно сообщения на C# WinForms
- Свое модальное окно: ShowDialog
- Немодальное окно: Show
- Когда какое окно выбирать
- Если не получилось
- Выводы
- Где применяется / связь с практикой
- FAQ
Ниже — словарь терминов, виды диалогов с таблицей, стандартные окна Windows, смысл кнопок ОК, Отмена и Применить и рабочий пример на C# WinForms: окно сообщения, собственный модальный диалог и немодальное окно.
Окно, диалоговое окно и окно сообщения: в чем разница
Эти слова часто используют как синонимы, хотя это разные уровни:
- Окно — любая прямоугольная область программы с рамкой: главное окно Проводника, окно браузера, окно редактора.
- Диалоговое окно — вспомогательное окно для короткого обмена «вопрос — ответ» с пользователем. Обычно у него фиксированный размер, нет кнопок свернуть и развернуть, есть кнопки подтверждения.
- Окно сообщения (message box) — самый простой диалог: текст, значок и одна-три кнопки. В Windows его показывает системная функция
MessageBox, в .NET — классMessageBox. - Окно-владелец (owner) — окно, к которому привязан диалог. Диалог держится поверх владельца и при модальном показе блокирует именно его.
Модальные и немодальные диалоговые окна
Модальное окно не дает работать с окном-владельцем, пока его не закрыть: нажать ОК, Отмена или крестик. Программа ждет ответа и только потом продолжает действие. Немодальное окно открыто параллельно с основным: можно переключаться между ними, как между окном «Найти и заменить» и текстом документа.
| Вид | Что блокирует | Где встречается |
|---|---|---|
| Модальный к окну-владельцу | Окно-владелец (в WinForms при ShowDialog — и остальные окна этого приложения) |
Подтверждение удаления, «Сохранить как», настройки |
| Модальный к документу (sheet) | Только одно окно документа, остальные окна программы доступны | Типично для macOS: диалог «выезжает» из заголовка окна |
| Системно-модальный | Поверх всех окон; в современных Windows другие программы при этом не блокируются | Редкие критические предупреждения |
| Немодальный | Ничего | «Найти и заменить», палитры и панели инструментов |
Граница упрощения: точная область блокировки зависит от платформы и от того, как программа назначила владельца. Например, окно сообщения без владельца может не заблокировать главное окно, и пользователь продолжит работу с ним, пока вопрос висит на экране.
Стандартные диалоги Windows
Для типовых задач Windows дает готовые окна (common dialogs). Программе не нужно рисовать свой выбор файла: она вызывает системный диалог, и пользователь видит привычный интерфейс.
| Задача | Системный диалог | Класс в WinForms |
|---|---|---|
| Открыть файл | «Открытие» | OpenFileDialog |
| Сохранить файл | «Сохранить как» | SaveFileDialog |
| Выбрать папку | «Выбор папки» | FolderBrowserDialog |
| Выбрать цвет / шрифт | «Цвет» / «Шрифт» | ColorDialog / FontDialog |
| Печать | «Печать» | PrintDialog |
| Сообщение или вопрос | Окно сообщения | MessageBox |
| Вопрос с пояснением и вариантами | Диалог задачи (task dialog) | TaskDialog |
Все они по умолчанию модальные: код, открывший диалог, продолжится только после его закрытия.
Кнопки ОК, Отмена и Применить
| Кнопка | Что делает | Закрывает окно |
|---|---|---|
| ОК | Применяет изменения | Да |
| Отмена | Отбрасывает изменения, сделанные в окне | Да |
| Применить | Применяет изменения, чтобы сразу увидеть результат | Нет |
| Закрыть | Закрывает окно, где изменения уже применены сразу | Да |
Частая путаница: «Применить» — не аналог ОК. После «Применить» окно остается открытым, а «Отмена» уже не вернет примененное. По соглашению Windows клавиша Enter нажимает кнопку по умолчанию, а Esc — кнопку отмены.
Пример: окно сообщения на C# WinForms
Пример работает только в Windows: WinForms — библиотека Windows. Нужен .NET SDK 10. Создайте проект командой dotnet new winforms -n DialogsDemo, удалите файлы Form1.cs и Form1.Designer.cs, замените Program.cs кодом ниже и запустите dotnet run в папке проекта.
namespace DialogsDemo;
static class Program
{
[STAThread]
static void Main()
{
ApplicationConfiguration.Initialize();
Application.Run(new MainForm());
}
}
class MainForm : Form
{
public MainForm()
{
Text = "Демо диалогов";
var deleteButton = new Button { Text = "Удалить файл", AutoSize = true };
deleteButton.Click += OnDeleteClick;
Controls.Add(deleteButton);
}
private void OnDeleteClick(object? sender, EventArgs e)
{
DialogResult answer = MessageBox.Show(
this, // владелец: окно, которое блокируется
"Удалить файл report.txt?", // текст
"Подтверждение", // заголовок
MessageBoxButtons.YesNo, // кнопки
MessageBoxIcon.Warning, // значок
MessageBoxDefaultButton.Button2); // по Enter сработает «Нет»
if (answer == DialogResult.Yes)
{
MessageBox.Show(this, "Файл удален (в демо ничего не удаляется).", "Готово",
MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
}
Что произойдет: откроется окно «Демо диалогов» с кнопкой «Удалить файл». По нажатию появится окно «Подтверждение» с желтым значком предупреждения и кнопками «Да» и «Нет». Пока оно открыто, главное окно не реагирует на клики. На «Да» появится второе окно «Готово», на «Нет» или Esc окно просто закроется.
Разбор по строкам:
MessageBox.Show(...)показывает модальное окно и возвращает, какую кнопку нажал пользователь, в виде значенияDialogResult.- Первый аргумент
this— окно-владелец. Без него диалог может уйти под другое окно или не заблокировать нужное. MessageBoxDefaultButton.Button2делает кнопкой по умолчанию вторую («Нет»). Для опасных действий это защищает от случайного Enter.
Типичная ошибка: сравнение ответа со строкой
Неверно — сравнивать результат с текстом кнопки:
if (MessageBox.Show("Удалить файл?", "Подтверждение", MessageBoxButtons.YesNo) == "Yes")
{
MessageBox.Show("Удалено");
}
Результат — проект не собирается:
Program.cs(8,13): error CS0019: Operator '==' cannot be applied to operands of type 'DialogResult' and 'string'
Исправление: сравнивать с перечислением — == DialogResult.Yes. Так код не зависит от языка интерфейса: в русской Windows кнопка подписана «Да», а значение остается тем же.
Свое модальное окно: ShowDialog
Когда окна сообщения мало (нужно поле ввода), делают свою форму и показывают ее методом ShowDialog. Добавьте в проект файл RenameDialog.cs:
namespace DialogsDemo;
// Собственное модальное окно: поле ввода + кнопки ОК и Отмена
class RenameDialog : Form
{
private readonly TextBox nameBox = new() { Width = 220 };
public string NewName => nameBox.Text.Trim();
public RenameDialog(string currentName)
{
Text = "Переименовать";
FormBorderStyle = FormBorderStyle.FixedDialog; // рамка диалога, без растягивания
MaximizeBox = false;
MinimizeBox = false;
ShowInTaskbar = false;
StartPosition = FormStartPosition.CenterParent;
AutoSize = true;
AutoSizeMode = AutoSizeMode.GrowAndShrink;
nameBox.Text = currentName;
var ok = new Button { Text = "ОК", DialogResult = DialogResult.OK };
var cancel = new Button { Text = "Отмена", DialogResult = DialogResult.Cancel };
AcceptButton = ok; // Enter
CancelButton = cancel; // Esc
var layout = new FlowLayoutPanel { AutoSize = true, Padding = new Padding(10) };
layout.Controls.AddRange([nameBox, ok, cancel]);
Controls.Add(layout);
}
}
Вызов из главного окна:
using var dialog = new RenameDialog("report.txt");
if (dialog.ShowDialog(this) == DialogResult.OK && dialog.NewName.Length > 0)
{
Text = "Новое имя: " + dialog.NewName;
}
// сюда выполнение доходит только после закрытия окна
Ключевые детали. Свойство DialogResult у кнопки закрывает модальную форму и передает значение в результат ShowDialog, отдельный обработчик клика не нужен. AcceptButton и CancelButton привязывают Enter и Esc. using нужен потому, что форма после ShowDialog не уничтожается автоматически, в отличие от окна, открытого через Show.
Немодальное окно: Show
private Form? findWindow;
private void ShowFind()
{
if (findWindow is { IsDisposed: false })
{
findWindow.Activate(); // уже открыто: просто выводим вперед
return;
}
findWindow = new Form { Text = "Найти", Width = 300, Height = 120 };
findWindow.Show(this); // немодально: главное окно остается доступным
// эта строка выполнится сразу, не дожидаясь закрытия окна «Найти»
}
Окно «Найти» держится поверх главного и сворачивается вместе с ним, потому что передан владелец this. Проверка IsDisposed не дает открыть десять копий одного окна.
ShowDialog |
Show |
|
|---|---|---|
| Режим | Модальный | Немодальный |
| Ждет закрытия | Да, возвращает DialogResult |
Нет, код идет дальше |
| Работа с главным окном | Заблокирована | Доступна |
| После закрытия | Форму нужно освободить (using или Dispose) |
Форма освобождается сама |
| Типичное применение | Вопрос, ввод, настройки с ОК/Отмена | Поиск, палитры, окна свойств |
Когда какое окно выбирать
Модальный диалог оправдан, если без ответа нельзя продолжить: подтвердить необратимое действие, ввести имя для сохранения, выбрать файл. Изменения в таком окне обычно применяются по ОК (отложенная фиксация).
Немодальное окно подходит для частых повторяющихся задач, когда пользователь работает с документом и инструментом одновременно. Изменения в нем обычно применяются сразу, а вместо ОК и Отмена ставят «Закрыть».
Это ориентиры из руководств по интерфейсу, а не жесткое правило. Слишком частые подтверждения пользователи начинают закрывать не читая, поэтому для опасных операций надежнее возможность отмены (корзина, Ctrl+Z), чем еще одно окно «Вы уверены?».
Долгую операцию показывают окном хода выполнения с кнопкой «Отмена». Если программа в фоне и ей нужно внимание, не выводите окно поверх чужой работы: достаточно подсветить кнопку на панели задач.
Если не получилось
| Симптом | Причина | Что сделать |
|---|---|---|
| Ошибка сборки NETSDK1100 на Linux или macOS | Проект под net10.0-windows |
Собирать в Windows или добавить <EnableWindowsTargeting>true</EnableWindowsTargeting> (только сборка, запуск все равно в Windows) |
| Диалог спрятался за главным окном | Не передан владелец | Передать this в MessageBox.Show и ShowDialog |
| Код после показа окна выполнился сразу | Вызван Show вместо ShowDialog |
Для ответа пользователя — ShowDialog |
| Enter или Esc не срабатывают | Не заданы AcceptButton и CancelButton |
Назначить обе кнопки формы |
| Открывается несколько копий окна | Новая форма на каждый клик | Хранить ссылку и проверять IsDisposed |
Выводы
- Диалоговое окно — вспомогательное окно для обмена «вопрос — ответ»; окно сообщения — его простейший вид.
- Модальное окно блокирует владельца до закрытия и возвращает ответ; немодальное работает параллельно с основным окном.
- «Применить» применяет изменения без закрытия окна, ОК — с закрытием, Отмена — закрывает без изменений.
- В C# WinForms модальный показ —
MessageBox.ShowиShowDialog, немодальный —Show(owner); ответ сравнивают сDialogResult, а не со строкой. - Для опасных действий возможность отмены надежнее, чем лишнее окно подтверждения.
Где применяется / связь с практикой
Диалоги встречаются в любом настольном приложении: редакторы, утилиты администрирования, внутренние корпоративные программы. Разработчик на C# собирает их в WinForms или WPF, и от того, модальный это диалог или нет, зависит логика кода: ждать ответа или продолжать работу.
Освойте тему на практике
Если хотите системно освоить C# — от синтаксиса и ООП до событий и работы с формами, — посмотрите курс «C# Developer. Basic». Разобрать отдельные темы с преподавателями можно на бесплатных открытых уроках Otus.
FAQ
Можно ли закрыть модальное окно крестиком?
Да. В WinForms это дает результат DialogResult.Cancel, поэтому крестик обрабатывают как отмену, а не как согласие.
Чем диалог задачи (TaskDialog) лучше MessageBox?
В нем есть заголовок-инструкция, пояснение, собственные подписи кнопок, флажок «Больше не спрашивать» и индикатор выполнения. MessageBox проще и подходит для короткого сообщения.
Есть ли диалоговые окна в WPF и на веб-страницах?
Да. В WPF окно показывают модально через ShowDialog и немодально через Show, в HTML есть элемент dialog с методами showModal() и show(). Принцип модальности тот же.



