Fix issue 14772: Button hosted on a TabPage does not use the Windows accent-colored focus indicator with VisualStylesMode = NET11 - #14860
Conversation
…accent-colored focus indicator with VisualStylesMode = NET11
There was a problem hiding this comment.
Pull request overview
Fixes WinForms VisualStylesMode inheritance/override semantics so a child control explicitly set to the same mode as its parent does not silently revert to Inherit, which resolves the TabPage-hosted button accent-focus inconsistency in .NET 11 (VisualStylesMode = Net11) scenarios.
Changes:
- Updated
Control.VisualStylesModesetter logic to only clear a local override when explicitly set toInherit, or when intentionally transitioning an existing override back to the ambient (parent) value. - Refined
ButtonDarkModeAdapterbackground color selection so modern (.NET 11) default-button behavior remains accent-driven while classic paths avoid unintended ambient-color influence. - Added regression tests covering the new VisualStylesMode semantics and button rendering behavior across TabPage vs non-TabPage hosting and explicit vs inherited BackColor.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| src/test/unit/System.Windows.Forms/System/Windows/Forms/ControlTests.VisualStylesMode.cs | Adds regression coverage for “first set to ambient value should remain a local override” semantics. |
| src/test/unit/System.Windows.Forms/System/Windows/Forms/ButtonVisualStylesTests.cs | Adds rendering/regression tests for modern default-button accent behavior and classic-vs-modern BackColor handling. |
| src/System.Windows.Forms/System/Windows/Forms/Controls/Buttons/ButtonInternal/DarkMode/ButtonDarkModeAdapter.cs | Adjusts back-color selection rules to keep Net11 default buttons accent-driven and prevent classic mode from being influenced by ambient background in modern hierarchies. |
| src/System.Windows.Forms/System/Windows/Forms/Control.cs | Updates VisualStylesMode override-clearing logic to avoid unintended reversion to Inherit. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Hey, could you record a short video, where you - in addition - also Tab through the controls with the Tab key, and see, how the focus indicator looks then through out? Thx! |
Done. I’ve recorded a short video and uploaded it to the "Screenshots" section. The focus indicator displays well when using the Tab key. Feel free to let me know if you need me to test any other scenarios. |
| { | ||
| bool hasExplicitBackColor = Control.ShouldSerializeBackColor(); | ||
| bool hasUsableAmbientBackColor = _modern | ||
| && !Control.BackColor.HasTransparency() |
There was a problem hiding this comment.
This change makes a Classic button ignore a non-default BackColor inherited from its parent. Before this PR, Control.BackColor—including an ambient value—was passed to the renderer whenever it differed from DefaultBackColor. After this change, ambient colors are accepted only when _modern is true. Consequently, a Classic button on a custom-colored container now renders with the default palette instead of the inherited color. This appears to be a behavioral regression and contradicts the PR description that the Classic path retains its original behavior.
Fixes #14772
##Root Cause
When setting a value for
Control.VisualStylesMode, the system treats "setting the child control to the same value currently held by the parent" as "reverting to ambient (inherited) behavior," thereby clearing any local override. Consequently, a child control that appears to be set toClassicactually becomesInherit; if the parent container later switches toNet11, the child control passively inherits that setting and enables the accent style. This phenomenon is further amplified because the button's implementation includes the ambient background in the modern color-selection logic.Proposed changes
Control.VisualStylesMode: Only theInheritsetting unconditionally clears the local value; the "same as parent" setting clears the local value only when there is an existing local override that is explicitly switched back to "ambient."ButtonDarkModeAdapter: Logic for determining accent/default colors and ambient background states now applies only to the_modern(.NET 11) code path, while theClassicpath retains its original behavior.TabPagevs. non-TabPagescenarios, and explicit vs. inheritedBackColorsettings.Customer Impact
Regression?
Risk
Screenshots
Before
After
2026-08-06.151846.mp4
14860.mp4
Test methodology
Test environment(s)
Microsoft Reviewers: Open in CodeFlow