Skip to content

DarkMode (b) DarkModeButtonRenderer #13408

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 9 commits into
base: klaus/preview5/A
Choose a base branch
from

Conversation

KlausLoeffelmann
Copy link
Member

@KlausLoeffelmann KlausLoeffelmann commented May 5, 2025

Add a DarkModeButton Renderer based on our existing ButtonFlatRenderer.

This way, we are getting completely independing of the XP-based VisualStyle rendering (and most of all incomplete theming for certain situations, like the Button rendering for 96DPI/100% scaling scenarios).

Fixes #11949.

Note:
The current DarkMode PRs need to be tested as a whole, so they are always rebased on each other, hence the "sorting" letters in the PR titles.

Since each of them carries from a review point of view every change of also of the one, the respective next is based on, I pushed also the "based-on PRs" as branches to the main repo, and had GitHub the PRs to review based on them, so you will ONLY see the changes for that particular PR.

image

Approach

TL;DR
Four sub-renderers are needed to faithfully reproduce the visual and interactive nuances of each FlatStyle in dark mode, ensuring both compatibility and a polished user experience.

The ButtonDarkModeRenderer is designed to render buttons with a modern, dark-themed appearance, while preserving the flexibility and compatibility required by the classic WinForms Button control. It achieves this by abstracting the rendering logic into a set of interchangeable renderer classes, each tailored to a specific FlatStyle.

Why Four Different Sub-Renderers?

WinForms Button supports four FlatStyle values, each with distinct visual and behavioral requirements. It was the goal, to find appropriate equivalents for each style in dark mode.

  • Standard: Classic button with system-like appearance.
  • Flat: Minimalist, border-only button with no background fill.
  • Popup: Button with a subtle 3D effect, often used for toolbars or context menus.
  • System: Used to delegate the rendering to the VisualStyle OS-calls for a native look. We have replaced this, to get closer to the style, that the Fluent Style does for WPF and how WinUI renders Buttons.

Each style has unique needs for borders, backgrounds, focus cues, and interaction feedback. To provide accurate dark mode support for all these styles, the renderer system uses four sub-renderers classes:

  1. StandardButtonDarkModeRenderer
    Handles the default look, with subtle visual effects for Mouse hover and click.

  2. FlatButtonDarkModeRenderer
    Renders a border-only button, with minimal effects and minimal background coloring, matching the original, minimalistic flat style.

  3. PopupButtonDarkModeRenderer
    Provides a subtle 3D effect with rounded corners and shadow/highlight borders, suitable for popup-style buttons.

  4. SystemButtonDarkModeRenderer
    Mimics the Fluent Style for WPF and how WinUI renders Buttons.

CodeFlow

  • The main ButtonDarkModeRenderer selects the appropriate sub-renderer based on the button’s FlatStyle.
  • Each sub-renderer implements a common interface (IButtonDarkModeRenderer) with methods for drawing the background, focus indicator, and determining text color.
  • The sub-renderers encapsulate all style-specific logic, such as border thickness, corner radius, color selection, and focus cues.
  • This separation ensures that each button style is rendered accurately in dark mode, while keeping the code maintainable and extensible.

Summary Table

FlatStyle Renderer Key Features in Dark Mode
Standard StandardButtonDarkModeRenderer 3D borders, classic look, dark colors
Flat FlatButtonDarkModeRenderer Minimal border, hover/press feedback
Popup PopupButtonDarkModeRenderer Subtle 3D, rounded corners, shadow lines
System SystemButtonDarkModeRenderer WinUI look and feel.
Microsoft Reviewers: Open in CodeFlow

@KlausLoeffelmann KlausLoeffelmann self-assigned this May 5, 2025
@KlausLoeffelmann KlausLoeffelmann added area-DarkMode Issues relating to Dark Mode feature and removed needs-area-label labels May 5, 2025
@dotnet-policy-service dotnet-policy-service bot added the draft draft PR label May 5, 2025
@KlausLoeffelmann KlausLoeffelmann force-pushed the DarkMode_b_DarkModeButtonRenderer branch 2 times, most recently from 57f4d2f to 3b45170 Compare May 9, 2025 22:12
Copy link

codecov bot commented May 9, 2025

Codecov Report

Attention: Patch coverage is 12.64546% with 1126 lines in your changes missing coverage. Please review.

Project coverage is 76.48147%. Comparing base (c78c1e9) to head (b83e93b).

Additional details and impacted files
@@                 Coverage Diff                 @@
##                main      #13408         +/-   ##
===================================================
- Coverage   76.60074%   76.48147%   -0.11928%     
===================================================
  Files           3230        3239          +9     
  Lines         639097      640227       +1130     
  Branches       47289       47402        +113     
===================================================
+ Hits          489553      489655        +102     
- Misses        145962      146996       +1034     
+ Partials        3582        3576          -6     
Flag Coverage Δ
Debug 76.48147% <12.64546%> (-0.11928%) ⬇️
integration 18.73882% <5.04267%> (-0.04191%) ⬇️
production 50.83950% <12.64546%> (-0.16490%) ⬇️
test 97.40411% <ø> (ø)
unit 48.24382% <12.64546%> (-0.17106%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@KlausLoeffelmann KlausLoeffelmann force-pushed the DarkMode_b_DarkModeButtonRenderer branch 5 times, most recently from c2e7374 to 2530362 Compare May 16, 2025 06:43
@KlausLoeffelmann KlausLoeffelmann force-pushed the DarkMode_b_DarkModeButtonRenderer branch from 918e60d to b83e93b Compare May 16, 2025 22:10
@KlausLoeffelmann KlausLoeffelmann marked this pull request as ready for review May 17, 2025 00:41
@KlausLoeffelmann KlausLoeffelmann requested a review from a team as a code owner May 17, 2025 00:41
@dotnet-policy-service dotnet-policy-service bot removed the draft draft PR label May 17, 2025
@KlausLoeffelmann KlausLoeffelmann changed the base branch from main to klaus/preview5/A May 17, 2025 04:26
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
Projects
None yet
1 participant