Fix TabControl dark mode rendering for Left/Right alignment with vertical text rotation, dark tab strip, and dark border#14579
Open
SimonZhao888 wants to merge 1 commit into
Open
Conversation
…ical text rotation, dark tab strip, and dark border
Contributor
There was a problem hiding this comment.
Pull request overview
This PR updates TabControl dark-mode rendering for Left/Right (vertical) tab alignment by enabling automatic owner-draw and adding custom background/border painting paths, addressing a gap in Windows theming support for TCS_VERTICAL in dark mode (Fixes #14109).
Changes:
- Automatically sets
TCS_OWNERDRAWFIXEDfor vertical tabs when dark mode is enabled (unless explicitly owner-drawn by the user). - Adds default dark-mode vertical tab rendering with rotated text via
Graphics.DrawString. - Adds
WM_ERASEBKGND/WM_PAINThandling to darken the tab strip background and cover native light borders for vertical tabs.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+2207
to
+2211
| g.FillRectangle(borderBrush, | ||
| displayRect.Right, | ||
| displayRect.Y - borderThickness, | ||
| 0, | ||
| displayRect.Height + borderThickness * 2); |
Comment on lines
+2177
to
+2179
| if (Application.IsDarkModeEnabled && | ||
| (_alignment is TabAlignment.Left or TabAlignment.Right) && | ||
| _drawMode != TabDrawMode.OwnerDrawFixed) |
Comment on lines
+2223
to
+2226
| if (Application.IsDarkModeEnabled && | ||
| (_alignment is TabAlignment.Left or TabAlignment.Right) && | ||
| _drawMode != TabDrawMode.OwnerDrawFixed && | ||
| m.WParamInternal != (WPARAM)0) |
Comment on lines
+1379
to
+1382
| using (Pen pen = new(borderColor)) | ||
| { | ||
| e.Graphics.DrawRectangle(pen, e.Bounds.X, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #14109
Proposed changes
TCS_OWNERDRAWFIXED) for vertical tabs (Left/Right alignment) when dark mode is enabledDrawDarkModeTab()method with proper vertical text rotation usingGraphics.DrawString(GDI+) and very dark/black backgroundsOnDrawItem()to automatically render vertical tabs in dark mode when user hasn't set custom draw handlerWM_ERASEBKGNDmessage handling to paint tab strip background dark for vertical tabsWM_PAINTmessage handling to fill thick dark border areas around TabPage content for vertical tabsDarkMode::FileExplorerBannerContainerthemeDrawModeis not explicitly set toOwnerDrawFixedand noDrawItemevent handler is attachedRoot Cause: Windows standard themes (
DarkMode::FileExplorerBannerContainerandDarkMode_Explorer) do not support dark mode rendering for tab controls with theTCS_VERTICALstyle (Left/Right alignment). After testing multiple theme-based approaches, an owner-draw solution was implemented.Technical Implementation: Uses
Graphics.DrawStringinstead ofTextRenderer.DrawTextbecause TextRenderer is GDI-based and doesn't respect Graphics rotation transforms, while Graphics.DrawString uses GDI+ and properly honors rotation. Custom WM_PAINT handling fills 3-pixel thick border areas (top, bottom, left, right) around TabPage content area to completely cover the native Windows light border with dark color matching the tab strip background.Customer Impact
Application.SetColorMode(SystemColorMode.Dark)with vertically-aligned tab controlsDrawMode.OwnerDrawFixedsettings and customDrawItemevent handlers are preservedRegression?
Risk
Screenshots
Before
Left and Right alignments show white tabs in dark mode (highlighted in red boxes):
After
Manual testing on Windows required - Vertical tabs (Left/Right alignment) should now render with:
#252526, Normal tab#1C1C1C, Border#333333#2D2D30(the area where tabs are placed)#2D2D30(matching tab strip color)#F1F1F1Test methodology
Accessibility testing
Test environment(s)
Microsoft Reviewers: Open in CodeFlow