CheckBox в C#: как пользоваться флажком в WinForms
CheckBox в Windows Forms отвечает за выбор "да или нет": галочка стоит или не стоит. Ниже разобраны свойства и события, работа с тремя состояниями, набор флажков, сохранение настроек и частые ошибки, а все примеры рассчитаны на .NET 8 и Visual Studio 2022.

Содержание
- Что такое CheckBox и когда его использовать
- Основные свойства и события
- Создание CheckBox и обработка события
- Три состояния: ThreeState и Indeterminate
- Несколько флажков: сбор выбранных значений
- CheckBox в связке с другими элементами
- CheckBox в DataGridView и CheckedListBox
- Сохранение состояния между запусками
- Внешний вид и поведение
- Типичные ошибки
- CheckBox в WPF
- Частые вопросы
Что такое CheckBox и когда его использовать
CheckBox - это флажок с подписью, который хранит логическое значение. В отличие от переключателей RadioButton, флажки независимы: пользователь может отметить любое их количество, в том числе ни одного. Поэтому CheckBox подходит для параметров вроде "Запомнить меня", "Показывать скрытые файлы" или "Подписаться на рассылку", а для выбора ровно одного варианта из списка лучше брать RadioButton.
Элемент лежит в пространстве имён System.Windows.Forms и находится в панели элементов Visual Studio в разделе "Стандартные элементы управления". Любой проект Windows Forms, будь то .NET Framework или современный .NET 8, работает с ним одинаково. Если вы только начинаете строить окна, сначала загляните в статью про создание оконных приложений на C#.
Основные свойства и события
Для повседневной работы хватает нескольких членов класса. Они собраны в таблице.
| Член | Тип | Назначение |
|---|---|---|
Checked | bool | Стоит ли галочка. Для трёх состояний возвращает true и для Checked, и для Indeterminate |
CheckState | CheckState | Одно из значений: Unchecked, Checked, Indeterminate |
ThreeState | bool | Разрешает третье, неопределённое состояние при щелчке |
AutoCheck | bool | Если false, галочка не меняется сама, и решение принимает код |
Text | string | Подпись рядом с флажком |
Appearance | Appearance | Normal - обычная галочка, Button - кнопка с залипанием |
CheckAlign | ContentAlignment | Положение квадратика относительно подписи |
CheckedChanged | событие | Срабатывает при смене значения Checked |
CheckStateChanged | событие | Срабатывает при любой смене CheckState, включая переход в Indeterminate |
Событие Click тоже есть, но оно сообщает только о щелчке и не говорит, изменилось ли значение. Для реакции на смену состояния почти всегда нужен именно CheckedChanged.
Создание CheckBox и обработка события
Самый быстрый способ - перетащить элемент из панели на форму и в окне свойств задать Text и Name. Двойной щелчок по флажку создаст обработчик CheckedChanged. Тот же результат можно получить кодом, что удобно, когда число флажков заранее неизвестно.
using System;
using System.Drawing;
using System.Windows.Forms;
public class MainForm : Form
{
private readonly CheckBox chkAgree = new()
{
Text = "Я принимаю условия",
AutoSize = true,
Location = new Point(20, 20)
};
private readonly Button btnOk = new()
{
Text = "Продолжить",
Enabled = false,
Location = new Point(20, 55)
};
public MainForm()
{
chkAgree.CheckedChanged += (s, e) => btnOk.Enabled = chkAgree.Checked;
Controls.Add(chkAgree);
Controls.Add(btnOk);
}
[STAThread]
static void Main()
{
ApplicationConfiguration.Initialize();
Application.Run(new MainForm());
}
}
Кнопка недоступна, пока флажок не отмечен. Такой приём применяется в окнах с лицензионным соглашением и в формах подтверждения. Вызов ApplicationConfiguration.Initialize() появился в шаблонах .NET 6 и заменил пару из EnableVisualStyles и SetCompatibleTextRenderingDefault. В проекте на .NET Framework по-прежнему используются старые две строки.
Три состояния: ThreeState и Indeterminate
Если установить ThreeState = true, флажок получит промежуточное состояние. Оно показывается закрашенным квадратиком и означает "часть вложенных пунктов выбрана". Классический пример - флажок "Выбрать всё" над списком опций, где отмечена только часть строк.
private void UpdateMasterCheckBox()
{
var boxes = optionsPanel.Controls.OfType<CheckBox>().ToList();
int selected = boxes.Count(cb => cb.Checked);
chkAll.CheckState = selected == 0 ? CheckState.Unchecked
: selected == boxes.Count ? CheckState.Checked
: CheckState.Indeterminate;
}
Для OfType и Count нужна строка using System.Linq;. Учтите, что при установке CheckState из кода срабатывают события, поэтому легко получить рекурсию: главный флажок меняет дочерние, а дочерние пересчитывают главный. Чтобы этого избежать, заведите булев признак "идёт программное обновление" и выходите из обработчика, если он поднят.
Несколько флажков: сбор выбранных значений
Когда флажков много, отдельный обработчик на каждый неудобен. Разместите их в контейнере (GroupBox, Panel или FlowLayoutPanel) и пройдите по коллекции Controls. Ниже выбранные ингредиенты собираются в одну строку.
private void btnOrder_Click(object sender, EventArgs e)
{
var chosen = groupToppings.Controls
.OfType<CheckBox>()
.Where(cb => cb.Checked)
.Select(cb => cb.Text)
.ToList();
lblResult.Text = chosen.Count == 0
? "Ничего не выбрано"
: "Выбрано: " + string.Join(", ", chosen);
}
Если флажки создаются динамически, подпишитесь на один общий обработчик и различайте их через sender. Либо храните в свойстве Tag идентификатор записи, например номер товара, и используйте его при отправке заказа. Это позволяет не строить длинные цепочки if по именам элементов.
Динамическое создание флажков из списка
Часто набор опций приходит из базы или файла. Создавайте флажки циклом и складывайте их в FlowLayoutPanel, который сам расставит элементы по строкам.
string[] options = { "Сыр", "Грибы", "Ветчина", "Оливки" };
foreach (string option in options)
{
var cb = new CheckBox { Text = option, AutoSize = true, Tag = option };
cb.CheckedChanged += Option_CheckedChanged;
flowPanel.Controls.Add(cb);
}
private void Option_CheckedChanged(object? sender, EventArgs e)
{
if (sender is CheckBox cb)
statusLabel.Text = $"{cb.Text}: {(cb.Checked ? "да" : "нет")}";
}
CheckBox в связке с другими элементами
Типичные задачи, которые решаются одним флажком, перечислены ниже.
- Показать или скрыть пароль:
txtPassword.UseSystemPasswordChar = !chkShow.Checked; - Включить группу настроек:
groupAdvanced.Enabled = chkAdvanced.Checked; - Включить поле ввода:
txtCustom.Enabled = chkCustom.Checked; - Показать панель:
panelDetails.Visible = chkDetails.Checked; - Включить таймер:
timer1.Enabled = chkAuto.Checked;
Каждая строка помещается в обработчик CheckedChanged. Не забудьте и при загрузке формы привести зависимые элементы в соответствие с начальным значением флажка, иначе окно откроется в рассогласованном состоянии: например, галочка сохранена в настройках, а поле ввода остаётся заблокированным.
CheckBox в DataGridView и CheckedListBox
Если опций много и они выводятся списком, отдельные флажки на форме неудобны. Для этого есть два готовых решения. CheckedListBox показывает список строк с флажками и отдаёт отмеченные элементы через коллекцию CheckedItems. В таблице DataGridView можно добавить столбец типа DataGridViewCheckBoxColumn, который связывается с булевым полем источника данных.
// CheckedListBox
checkedListBox1.Items.AddRange(new object[] { "Москва", "Казань", "Самара" });
foreach (var item in checkedListBox1.CheckedItems)
Console.WriteLine(item);
// DataGridView: столбец с флажками
var col = new DataGridViewCheckBoxColumn { HeaderText = "Готово", DataPropertyName = "Done" };
dataGridView1.Columns.Add(col);
В DataGridView значение ячейки фиксируется только после того, как она теряет фокус. Если нужна мгновенная реакция, вызовите dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit) в обработчике CurrentCellDirtyStateChanged.
Сохранение состояния между запусками
Пользователи ожидают, что программа помнит их выбор. Самый простой путь - настройки приложения. Откройте свойства проекта, вкладку "Параметры", добавьте параметр типа bool с областью "Пользователь" и читайте его при загрузке формы, а записывайте при закрытии.
private void MainForm_Load(object sender, EventArgs e)
{
chkRemember.Checked = Properties.Settings.Default.RememberMe;
}
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{
Properties.Settings.Default.RememberMe = chkRemember.Checked;
Properties.Settings.Default.Save();
}
Если параметров много или нужен читаемый файл, используйте JSON: способы работы с ним показаны в статье про десериализацию JSON в C#.
Внешний вид и поведение
Свойство Appearance = Appearance.Button превращает флажок в залипающую кнопку, удобную для панелей инструментов: "Жирный", "Курсив", "Закрепить". Положение галочки меняется через CheckAlign, например ContentAlignment.MiddleRight ставит квадратик справа от подписи. Для длинного текста отключите AutoSize и задайте ширину, иначе подпись растянет форму.
Чтобы запретить пользователю менять значение, но не серить флажок, как при Enabled = false, поставьте AutoCheck = false и сами решайте в обработчике Click, менять ли Checked. Так делают, когда смена значения требует подтверждения, например через диалог MessageBox.
Типичные ошибки
- Обработчик
CheckedChangedсрабатывает при загрузке формы, потому что значение задаётся из кода или из настроек до того, как всё готово. Подписывайтесь на событие после начальной установки либо проверяйте признак загрузки. - Проверка
chk.CheckState == CheckState.Checkedдля флажка с тремя состояниями пропускает Indeterminate, аchk.Checkedсчитает его истиной. Определитесь, какое поведение нужно. - Изменение флажка из фонового потока вызывает исключение о межпотоковом доступе. Решение описано в статье про обновление интерфейса из другого потока.
- Много флажков с одинаковой логикой, написанных копированием кода. Заведите общий обработчик и используйте
sender. - Флажок используется там, где нужен выбор одного из вариантов. Тогда пользователь может отметить несовместимые пункты, и придётся писать лишние проверки. Берите RadioButton.
CheckBox в WPF
В WPF элемент называется так же, но состояние хранится в IsChecked, а тип свойства - bool?, то есть значение null соответствует неопределённому состоянию. События называются Checked, Unchecked и Indeterminate. Основной способ работы в WPF - привязка к модели представления.
<CheckBox Content="Запомнить меня" IsChecked="{Binding RememberMe, Mode=TwoWay}" />
В модели достаточно свойства bool RememberMe с уведомлением об изменении, и обработчики событий в коде окна не понадобятся.
Частые вопросы
Как узнать, отмечен ли CheckBox в C#?
Прочитайте свойство Checked: оно возвращает true, если галочка стоит. Для флажка с тремя состояниями проверяйте CheckState, чтобы отличить Checked от Indeterminate.
Чем CheckedChanged отличается от Click?
Click приходит на щелчок мышью, а CheckedChanged на каждую реальную смену значения, в том числе при установке Checked из кода. Для логики, зависящей от значения, берите CheckedChanged.
Как отметить все флажки сразу?
Пройдите по коллекции Controls контейнера: foreach (var cb in panel.Controls.OfType<CheckBox>()) cb.Checked = true;. Если у флажков есть общий обработчик, он сработает для каждого, поэтому на время массовой смены лучше его отключить.
Как сделать флажок недоступным для изменения?
Самый простой вариант - Enabled = false, но подпись при этом посереет. Если нужно сохранить обычный вид, задайте AutoCheck = false или отменяйте изменение в обработчике.
Как привязать CheckBox к данным?
В Windows Forms используйте chk.DataBindings.Add("Checked", source, "IsActive", true, DataSourceUpdateMode.OnPropertyChanged). Источником может быть объект с булевым свойством или таблица.
Можно ли использовать CheckBox без Windows Forms?
Да, у WPF, MAUI и Avalonia есть собственные флажки со схожей моделью, но свойства называются по-другому, например IsChecked. Логика из этой статьи переносится почти без изменений.





