CheckboxControl

June 14, 2026 · View on GitHub

Toggleable checkbox control with a label, checked/unchecked state, and keyboard/mouse support.

Overview

CheckboxControl displays a label next to a [ ] / [X] indicator and toggles its checked state when activated. It responds to keyboard (Space/Enter) and mouse clicks, and fires a CheckedChanged event whenever the state flips.

The checked and unchecked indicator characters are fully customizable, so the control can render anything from a classic X to a check mark (), a dot (), or any other single visible character. Colors for the normal, focused, and disabled states, as well as the checkmark itself, can be overridden or left to inherit from the active theme.

The control measures itself to a single row sized to [X] Label, but it also honors a fixed Width and HorizontalAlignment (including Stretch) when laid out inside containers.

See also: ButtonControl

Quick Start

var checkbox = Controls.Checkbox("Enable notifications")
    .Checked(true)
    .OnCheckedChanged((sender, isChecked) =>
    {
        // React to the new state
    })
    .Build();

window.AddControl(checkbox);

Builder API

Content

Controls.Checkbox("Label")           // Factory sets the initial label
    .WithLabel("Enable feature")     // Override the label text
    .Checked(true)                   // Set initial checked state (default: true when called)
    .Checked(false);                 // Explicitly start unchecked

Indicator Characters

Controls.Checkbox("Custom marks")
    .WithCheckedCharacter("✓")        // Character shown when checked (default "X")
    .WithUncheckedCharacter("·")      // Character shown when unchecked (default " ")
    .WithCheckmark("✓", "·");         // Set both at once (unchecked defaults to " ")

Layout

Controls.Checkbox("Label")
    .WithWidth(30)                              // Fixed width
    .WithAlignment(HorizontalAlignment.Center)  // Horizontal alignment
    .WithVerticalAlignment(VerticalAlignment.Top)
    .WithMargin(1)                              // Uniform margin
    .WithMargin(1, 0, 1, 0)                     // left, top, right, bottom
    .Visible(true)
    .StickyTop()                                // Stick to top of window
    .StickyBottom()                             // Stick to bottom of window
    .WithStickyPosition(StickyPosition.None);

Identity

Controls.Checkbox("Label")
    .WithName("myCheckbox")   // Name for FindControl<CheckboxControl>("myCheckbox")
    .WithTag(myData);         // Arbitrary tag object

Events

Controls.Checkbox("Label")
    .OnCheckedChanged((sender, isChecked) => { /* ... */ })
    .OnCheckedChanged((sender, isChecked, window) => { /* window-aware */ })
    .OnGotFocus((sender, e) => { /* ... */ })
    .OnGotFocus((sender, e, window) => { /* window-aware */ })
    .OnLostFocus((sender, e) => { /* ... */ })
    .OnLostFocus((sender, e, window) => { /* window-aware */ });

Properties

PropertyTypeDefaultDescription
CheckedboolfalseThe checked state; setting it fires CheckedChanged
Labelstring"Checkbox"Text displayed next to the checkbox
CheckedCharacterstring"X"Character shown inside the box when checked (empty/null falls back to default)
UncheckedCharacterstring" "Character shown inside the box when unchecked (empty/null falls back to default)
IsEnabledbooltrueWhether the checkbox can be interacted with
Widthint?nullFixed width (auto-sized to content if null)
BackgroundColorColor?nullBackground color in the normal state (uses theme if null)
ForegroundColorColortheme ButtonForegroundColor / Color.WhiteText color in the normal state
FocusedBackgroundColorColor?nullBackground color when focused (uses theme if null)
FocusedForegroundColorColortheme ButtonFocusedForegroundColor / Color.WhiteText color when focused
DisabledBackgroundColorColor?nullBackground color when disabled (uses theme if null)
DisabledForegroundColorColortheme ButtonDisabledForegroundColor / Color.DarkSlateGray1Text color when disabled
CheckmarkColorColortheme ButtonFocusedForegroundColor / Color.Cyan1Color of the checkmark character when checked
HasFocusboolfalseWhether the checkbox currently has keyboard focus
CanReceiveFocusbooltrueWhether the checkbox can receive focus (mirrors IsEnabled)
WantsMouseEventsbooltrueWhether the checkbox wants mouse events (mirrors IsEnabled)
CanFocusWithMousebooltrueWhether a mouse click can focus the checkbox (mirrors IsEnabled)

Events

EventArgumentsDescription
CheckedChangedEventHandler<bool>Fired when the checked state changes; argument is the new state
CheckedChangedAsyncAsyncEventHandler<bool>Async counterpart of CheckedChanged
MouseClickEventHandler<MouseEventArgs>Fired when the checkbox is left-clicked
MouseDoubleClickEventHandler<MouseEventArgs>Fired when the checkbox is double-clicked
MouseRightClickEventHandler<MouseEventArgs>Fired when the checkbox is right-clicked
MouseEnterEventHandler<MouseEventArgs>Fired when the mouse enters the checkbox area
MouseLeaveEventHandler<MouseEventArgs>Fired when the mouse leaves the checkbox area
MouseMoveEventHandler<MouseEventArgs>Fired when the mouse moves over the checkbox
GotFocusEventHandlerFired when the checkbox receives focus
LostFocusEventHandlerFired when the checkbox loses focus

Keyboard Support

KeyAction
SpaceToggle checked state
EnterToggle checked state
TabMove focus to next control
Shift+TabMove focus to previous control

Keys are only processed while the checkbox is enabled and focused.

Mouse Support

ActionResult
Left ClickToggle checked state and fire MouseClick
Double ClickFire MouseDoubleClick (does not toggle again)
Right ClickFire MouseRightClick
ClickGive the checkbox keyboard focus
Enter / LeaveFire MouseEnter / MouseLeave

Mouse events are only processed when enabled, and clicks in the control's margin area are ignored.

Examples

Simple Checkbox

window.AddControl(
    Controls.Checkbox("Enable notifications")
        .Checked(true)
        .Build()
);

Reacting to State Changes

window.AddControl(
    Controls.Checkbox("Auto-save on exit")
        .OnCheckedChanged((sender, isChecked) =>
        {
            windowSystem.NotificationStateService.ShowNotification(
                "Auto-save",
                isChecked ? "Enabled" : "Disabled",
                NotificationSeverity.Info
            );
        })
        .Build()
);

Custom Checkmark Characters

window.AddControl(
    Controls.Checkbox("Custom marks")
        .WithCheckmark("✓", "·")
        .Checked(true)
        .Build()
);

Reading State From Another Control

window.AddControl(
    Controls.Checkbox("Animate background gradient")
        .WithName("animToggle")
        .Checked(true)
        .Build()
);

// Elsewhere (e.g. an async window thread):
var toggle = window.FindControl<CheckboxControl>("animToggle");
if (toggle?.Checked == true)
{
    // run the animation
}

Two-Way Data Binding

var enabledCheckbox = Controls.Checkbox("Monitoring Enabled")
    .Build();

// Keep the view model and the checkbox in sync both ways
enabledCheckbox.BindTwoWay(vm, v => v.MonitoringEnabled, c => c.Checked);

window.AddControl(enabledCheckbox);

Settings Panel

panel.AddControl(Controls.Checkbox("Enable notifications").Checked(true).Build());
panel.AddControl(Controls.Checkbox("Auto-save on exit").Checked(true).Build());
panel.AddControl(Controls.Checkbox("Show status bar").Build());
panel.AddControl(Controls.Checkbox("Enable telemetry").Build());

Best Practices

  1. Use clear labels: The label should describe the option being toggled ("Enable notifications", not "Notifications?").
  2. Set the initial state explicitly: Use .Checked(true) for options that should default to on so the UI matches your model.
  3. Prefer CheckedChanged over polling: React to state changes through the event rather than reading Checked on a timer.
  4. Bind to your model: Use BindTwoWay to keep a view-model property and the checkbox in sync without manual event wiring. See the Data Binding guide.
  5. Name checkboxes you read later: Use .WithName(...) so you can retrieve state with FindControl<CheckboxControl>(...).
  6. Customize marks for clarity: Use WithCheckmark to match your visual style, but keep characters single-width for clean alignment.

See Also


Back to Controls | Back to Main Documentation