Skip to content

Fix CheckBox/RadioButton Appearance.Button + FlatStyle.Standard invisible in dark mode#14397

Open
ricardobossan wants to merge 1 commit intodotnet:mainfrom
ricardobossan:Issue_14347_CheckBox_And_RadioButton_Invisible_In_Dark_Mode
Open

Fix CheckBox/RadioButton Appearance.Button + FlatStyle.Standard invisible in dark mode#14397
ricardobossan wants to merge 1 commit intodotnet:mainfrom
ricardobossan:Issue_14347_CheckBox_And_RadioButton_Invisible_In_Dark_Mode

Conversation

@ricardobossan
Copy link
Member

@ricardobossan ricardobossan commented Mar 16, 2026

Fixes #14347

Root Cause

CheckBox and RadioButton with Appearance.Button + FlatStyle.Standard intentionally disabled owner-draw in dark mode to work around a VisualStyleRenderer HighDPI issue:

private protected override bool OwnerDraw =>
    (!Application.IsDarkModeEnabled
        || Appearance != Appearance.Button
        || FlatStyle != FlatStyle.Standard)
        && base.OwnerDraw;

With OwnerDraw = false, WinForms delegates painting to the native ComCtl32 button (BS_3STATE | BS_PUSHLIKE). The native control renders with light-mode colors (or transparent) on a dark form background, making the controls completely invisible.

Proposed changes

  • CheckBox.cs / RadioButton.cs: Remove the dark mode exception from OwnerDraw. Both controls now return base.OwnerDraw (i.e., FlatStyle != FlatStyle.System) unconditionally, restoring owner-draw for Appearance.Button + FlatStyle.Standard in dark mode.

  • CheckBoxStandardAdapter.cs / RadioButtonStandardAdapter.cs: Change CreateButtonAdapter() from new ButtonStandardAdapter(Control) to DarkModeAdapterFactory.CreateStandardAdapter(Control). In dark mode this returns ButtonDarkModeAdapter, which renders using explicit dark mode colors (#333333 background, #9B9B9B border, #F0F0F0 text) and does not use VisualStyleRenderers, resolving both the visibility issue and the HighDPI concern that motivated the original workaround.

Customer Impact

CheckBox and RadioButton controls with Appearance.Button + FlatStyle.Standard are now visible and correctly styled in dark mode. Previously they were completely invisible.

Regression?

No.

Risk

Minimal.

Screenshots

Before

Screenshot 2026-03-15 205030

After

Screenshot 2026-03-15 215221

Test methodology

Manual.

Test environment(s)

  • 11.0.100-preview.3.26161.119
Microsoft Reviewers: Open in CodeFlow

…ible in dark mode

Fixes dotnet#14347

`CheckBox` and `RadioButton` with `Appearance.Button + FlatStyle.Standard` intentionally disabled owner-draw in dark mode to work around a VisualStyleRenderer HighDPI issue:

```csharp
private protected override bool OwnerDraw =>
    (!Application.IsDarkModeEnabled
        || Appearance != Appearance.Button
        || FlatStyle != FlatStyle.Standard)
        && base.OwnerDraw;
```

With `OwnerDraw = false`, WinForms delegates painting to the native ComCtl32 button (`BS_3STATE | BS_PUSHLIKE`). The native control renders with light-mode colors (or transparent) on a dark form background, making the controls completely invisible.

- **`CheckBox.cs` / `RadioButton.cs`**: Remove the dark mode exception from `OwnerDraw`. Both controls now return `base.OwnerDraw` (i.e., `FlatStyle != FlatStyle.System`) unconditionally, restoring owner-draw for `Appearance.Button + FlatStyle.Standard` in dark mode.

- **`CheckBoxStandardAdapter.cs` / `RadioButtonStandardAdapter.cs`**: Change `CreateButtonAdapter()` from `new ButtonStandardAdapter(Control)` to `DarkModeAdapterFactory.CreateStandardAdapter(Control)`. In dark mode this returns `ButtonDarkModeAdapter`, which renders using explicit dark mode colors (`#333333` background, `#9B9B9B` border, `#F0F0F0` text) and does not use VisualStyleRenderers, resolving both the visibility issue and the HighDPI concern that motivated the original workaround.

`CheckBox` and `RadioButton` controls with `Appearance.Button + FlatStyle.Standard` are now visible and correctly styled in dark mode. Previously they were completely invisible.

No.

Minimal.

Manual.

- 11.0.100-preview.3.26161.119
@ricardobossan ricardobossan self-assigned this Mar 16, 2026
@ricardobossan ricardobossan requested a review from a team as a code owner March 16, 2026 01:32
@ricardobossan ricardobossan added the waiting-review This item is waiting on review by one or more members of team label Mar 16, 2026
@github-actions github-actions bot added the area-DarkMode Issues relating to Dark Mode feature label Mar 16, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes dark-mode invisibility for CheckBox/RadioButton when using Appearance.Button + FlatStyle.Standard by restoring owner-draw in dark mode and routing “button-like” rendering through a dark-mode-capable adapter.

Changes:

  • Remove dark-mode special-casing from OwnerDraw in CheckBox and RadioButton (now always base.OwnerDraw).
  • Use DarkModeAdapterFactory.CreateStandardAdapter(...) for the Appearance.Button rendering path in the Standard adapters.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

File Description
src/System.Windows.Forms/System/Windows/Forms/Controls/Buttons/RadioButton.cs Restores owner-draw in dark mode by removing the special OwnerDraw condition.
src/System.Windows.Forms/System/Windows/Forms/Controls/Buttons/CheckBox.cs Restores owner-draw in dark mode by removing the special OwnerDraw condition.
src/System.Windows.Forms/System/Windows/Forms/Controls/Buttons/ButtonInternal/RadioButtonStandardAdapter.cs Routes Appearance.Button painting through the dark-mode adapter factory.
src/System.Windows.Forms/System/Windows/Forms/Controls/Buttons/ButtonInternal/CheckBoxStandardAdapter.cs Routes Appearance.Button painting and sizing through the dark-mode adapter factory.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Comment on lines +176 to 177
private protected override bool OwnerDraw => base.OwnerDraw;

Comment on lines 109 to 111

protected override ButtonBaseAdapter CreateButtonAdapter() => new ButtonStandardAdapter(Control);
protected override ButtonBaseAdapter CreateButtonAdapter() => DarkModeAdapterFactory.CreateStandardAdapter(Control);

Comment on lines +53 to 56
private new ButtonBaseAdapter ButtonAdapter => base.ButtonAdapter;

protected override ButtonBaseAdapter CreateButtonAdapter() => new ButtonStandardAdapter(Control);
protected override ButtonBaseAdapter CreateButtonAdapter() => DarkModeAdapterFactory.CreateStandardAdapter(Control);

|| Appearance != Appearance.Button
|| FlatStyle != FlatStyle.Standard)
&& base.OwnerDraw;
private protected override bool OwnerDraw => base.OwnerDraw;
@LeafShi1
Copy link
Member

Should we enable OwnerDraw in Standard mode? @KlausLoeffelmann

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-DarkMode Issues relating to Dark Mode feature waiting-review This item is waiting on review by one or more members of team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[DarkMode] the checked/unchecked items cannot be seen after clicking the CustomComCtl32Button button in DarkMode for WinformsControlTest project

3 participants