[Windows] Fixed : Switch control default width issue#30538
[Windows] Fixed : Switch control default width issue#30538kubaflo merged 4 commits intodotnet:inflight/currentfrom
Conversation
|
Hey there @@Tamilarasan-Paranthaman! Thank you so much for your PR! Someone from the team will get assigned to your PR shortly and we'll get it reviewed. |
|
This is an old bug, thanks to finally address it! |
|
/azp run MAUI-UITests-public |
|
Azure Pipelines successfully started running 1 pipeline(s). |
There was a problem hiding this comment.
Pull Request Overview
This PR fixes an issue with Switch control sizing on Windows where the control was reserving unnecessary space due to WinUI's default MinWidth of 154 pixels, which was intended for OnContent/OffContent that .NET MAUI doesn't support.
- Overrides the native ToggleSwitch MinWidth based on MAUI's MinimumWidth property
- Removes unnecessary column spacing in the ToggleSwitch template that was reserved for unsupported content
- Adds UI tests to verify the fix works correctly
Reviewed Changes
Copilot reviewed 5 out of 15 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/Core/src/Platform/Windows/SwitchExtensions.cs | Adds UpdateMinWidth extension method to set ToggleSwitch MinWidth based on MAUI view's MinimumWidth |
| src/Core/src/Handlers/Switch/SwitchHandler.cs | Maps MinimumWidth property to the new handler method for Windows platform |
| src/Core/src/Handlers/Switch/SwitchHandler.Windows.cs | Implements MinimumWidth mapping and removes unnecessary column spacing from ToggleSwitch template |
| src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue28901.cs | Adds UI test to verify Switch control sizing behavior |
| src/Controls/tests/TestCases.HostApp/Issues/Issue28901.cs | Creates test page with Switch controls to demonstrate the sizing fix |
|
/azp run MAUI-UITests-public |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
/rebase |
19d36f6 to
31c6b72
Compare
|
any news on this issue? |
|
/rebase |
31c6b72 to
c514cfd
Compare
|
/azp run MAUI-UITests-public |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
FYI this works great: #28901 (comment) |
c514cfd to
a3ba803
Compare
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 30538Or
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 30538" |
🤖 AI Summary📊 Expand Full Review —
|
| # | Source | Approach | Test Result | Files Changed | Notes |
|---|---|---|---|---|---|
| PR | PR #30538 | Override WinUI ToggleSwitch.MinWidth from MAUI MinimumWidth, remove unused template spacing on load, and cover with Issue28901 UI test/snapshots |
PENDING (Gate) | SwitchHandler.Windows.cs, SwitchHandler.cs, SwitchExtensions.cs, Issue28901 test files |
Original PR |
🚦 Gate — Test Verification
Gate Result: PASSED
Result: PASSED
Platform: windows
Mode: Full Verification
- Tests FAIL without fix:
- Tests PASS with fix:
Evidence
- Issue28901.VerifySwitchControlSize() failed against the broken baseline with a screenshot diff (VerifySwitchControlSize.png, 2.61% difference).
- The same test passed with the PR fix restored.
- Verification details were captured in CustomAgentLogsTmp/PRState/30538/PRAgent/gate/verify-tests-fail/verification-report.md.
🔧 Fix — Analysis & Comparison
Fix Candidates
| # | Source | Approach | Test Result | Files Changed | Notes |
|---|---|---|---|---|---|
| 1 | try-fix | Set MinWidth = 0 in ConnectHandler, collapse OffContentPresenter/OnContentPresenter, and let columns auto-size |
FAIL | SwitchHandler.Windows.cs |
Functional but missed the existing screenshot baseline by 2.61% |
| 2 | try-fix | Set MinWidth = 0 in Loaded after base mapping, and zero the spacing column there |
PASS | SwitchHandler.Windows.cs |
Smallest passing alternative, but likely overrides explicit user MinimumWidth values |
| 3 | try-fix | Force template/layout compaction at connect-time using geometry/template parts | FAIL | SwitchHandler.Windows.cs, SwitchExtensions.cs |
Compile/API-surface blockers made the approach non-viable |
| 8 | try-fix | Override WinUI theme resources such as ToggleSwitchThemeMinWidth / spacing margins |
FAIL | SwitchHandler.Windows.cs, SwitchExtensions.cs |
Built, but caused runtime instability during the Windows test run |
| 9 | try-fix | Apply a MAUI-specific compact WinUI ToggleSwitch style/control template |
PASS | WinUI style XAML + handler/style wiring | Works, but copies a large WinUI template and adds maintenance burden |
| 10 | try-fix | Subclass ToggleSwitch, move spacing fix into template hook, and preserve explicit minimums in subclass logic |
FAIL | SwitchHandler.Windows.cs, SwitchHandler.cs, SwitchExtensions.cs |
Invalid because WinUI ToggleSwitch is sealed |
| PR | PR #30538 | Override WinUI ToggleSwitch.MinWidth from MAUI MinimumWidth, remove unused template spacing on load, and cover with Issue28901 UI test/snapshots |
✅ PASSED (Gate) | SwitchHandler.Windows.cs, SwitchHandler.cs, SwitchExtensions.cs, Issue28901 test files |
Original PR |
Cross-Pollination
| Model | Round | New Ideas? | Details |
|---|---|---|---|
| claude-opus-4.6 | 1 | Yes | MAUI-specific WinUI style/control-template path |
| claude-sonnet-4.6 | 1 | No | NO NEW IDEAS |
| gpt-5.3-codex | 1 | Yes | Theme-resource override for min width / spacing |
| gemini-3-pro-preview | 1 | Yes | Theme-resource override through WinUI style/binding system |
| claude-opus-4.6 | 2 | No | NO NEW IDEAS |
| claude-sonnet-4.6 | 2 | No | NO NEW IDEAS |
| gpt-5.3-codex | 2 | Yes | Subclass + template callback + explicit-minimum preservation |
| gemini-3-pro-preview | 2 | No | NO NEW IDEAS |
| claude-opus-4.6 | 3 | No | NO NEW IDEAS |
| claude-sonnet-4.6 | 3 | No | NO NEW IDEAS |
| gpt-5.3-codex | 3 | No | NO NEW IDEAS |
| gemini-3-pro-preview | 3 | No | NO NEW IDEAS |
Exhausted: Yes
Selected Fix: PR #30538 It passes the gate, preserves explicit MinimumWidth semantics via a switch-specific mapper, avoids the maintenance burden of a copied WinUI template, and is more robust than the smaller but behavior-risky loaded-only alternative.
📋 Report — Final Recommendation
Final Recommendation: APPROVE
Result: PASSED
Final Recommendation: APPROVE
Phase Status
| Phase | Status | Notes |
|---|---|---|
| Pre-Flight | COMPLETE | Windows-only Switch sizing/alignment issues linked across #28901, #30273, and #10107 |
| Gate | PASSED | Windows Issue28901 screenshot test failed without the fix and passed with it |
| Try-Fix | COMPLETE | Exhausted 6 tracked alternative candidates; Selected Fix: PR #30538 |
| Report | COMPLETE |
Summary
PR #30538 fixes the Windows Switch sizing bug and its regression test genuinely catches the issue. Mandatory try-fix exploration found two passing alternatives, but the best small one (MinWidth = 0 in Loaded) appears to override explicit user MinimumWidth values, and the full template-based fix is much more invasive. The PR's current design is the best trade-off of correctness, maintainability, and scope.
Root Cause
WinUI's default ToggleSwitch template reserves minimum width and spacing for On/Off content that MAUI does not expose. On Windows, the base MapMinimumWidth path clears the local MinWidth value when no explicit MinimumWidth is set, which allows the WinUI default minimum width to reassert itself. The control also keeps an unnecessary internal spacing column for the unused content area.
Fix Quality
The PR addresses both parts of the problem with the right level of specificity:
- It overrides ToggleSwitch.MinWidth through a Switch-specific mapper so the default WinUI minimum width is suppressed while still respecting explicit MAUI MinimumWidth values.
- It removes the unnecessary spacing column during Loaded, which is the viable timing point for mutating the realized WinUI visual tree.
- It adds an issue-specific UI test that fails without the fix and passes with it on Windows.
Compared with the alternatives explored, this is the strongest solution:
- Smaller loaded-only alternatives risk regressing explicit MinimumWidth behavior.
- Theme-resource approaches were unstable.
- Template-copy approaches work but add substantial maintenance overhead.
- Subclass/template-hook ideas are blocked because WinUI ToggleSwitch is sealed.
<!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! <!-- !!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING MAIN. !!!!!!! --> ### Root Cause of the issue - The native WinUI ToggleSwitch control defines a default [MinWidth](https://github.com/microsoft/microsoft-ui-xaml/blob/a3021d80977fecc7d6ca33dc94dc500c5535faab/src/controls/dev/CommonStyles/ToggleSwitch_themeresources.xaml#L188C20-L188C45) of 154 in its style, likely to accommodate the OnContent and OffContent values supported in WinUI. However, since .NET MAUI does not support displaying these contents, the default minimum width is unnecessary. As a result, the control always reserves that space, leading to unnecessary space usage in .NET MAUI. ### Description of Change - The native ToggleSwitch's minimum width is now set based on the MinimumWidthRequest value provided by the MAUI Switch view. Since MAUI does not support OnContent and OffContent, the default width is unnecessary. This change ensures the control's width reflects the actual layout requirement, resolving the unwanted spacing issue. ### Reference - [ToggleSwitchThemeMinWidth](https://github.com/microsoft/microsoft-ui-xaml/blob/a3021d80977fecc7d6ca33dc94dc500c5535faab/src/controls/dev/CommonStyles/ToggleSwitch_themeresources.xaml#L188C20-L188C45) - [DefaultSpacing](https://github.com/microsoft/microsoft-ui-xaml/blob/a3021d80977fecc7d6ca33dc94dc500c5535faab/src/controls/dev/CommonStyles/ToggleSwitch_themeresources.xaml#L501) ### Issues Fixed Fixes #28901 Fixes #30273 Fixes #10107 ### Tested the behaviour in the following platforms - [x] iOS - [x] Mac - [x] Android - [x] Windows ### Screenshot | Before Fix | After Fix | |----------|----------| | <video src="https://github.com/user-attachments/assets/d8f0c4da-1199-457f-8186-4bf80495c9c8"> | <video src="https://github.com/user-attachments/assets/8128cfbf-1aaf-46c9-a059-45e512114f73"> |
…sample on candidate (#34697) ### Details PR #30538 fixes the Windows Switch control width issue, where it previously reserved unnecessary space inherited from WinUI’s ToggleSwitch default style. Due to this change, we need to re-save the existing switch images. Also the reduced Switch width, the grid columns in AppThemePage are rebalanced, causing the RadioButton (which has Grid.ColumnSpan="2") to overlap the Editor control on the right side. ### Description of Change: - Before: RadioButton had Grid.ColumnSpan="2", causing it to span both columns and overlap the Editor in Column 1 of the same row. - After: RadioButton is constrained to Grid.Column="0" only, so the Editor in Column 1 remains in its own cell without overlap. ### Failures caused by these PRs: #30538 - The Switch previously occupied the full width; now it takes only the required space. #30089 - The Slider previously appeared without a background color, now the background color is applied correctly. ### Screenshots | Before Issue Fix | After Issue Fix | |----------|----------| | <img width="300" height="600" src="https://github.com/user-attachments/assets/ac70ad29-f055-4870-b9b2-5a381f601254"> | <img width="300" height="600" src="https://github.com/user-attachments/assets/a06482bf-c0de-4c27-87be-d9d00a503723"> |
<!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! <!-- !!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING MAIN. !!!!!!! --> ### Root Cause of the issue - The native WinUI ToggleSwitch control defines a default [MinWidth](https://github.com/microsoft/microsoft-ui-xaml/blob/a3021d80977fecc7d6ca33dc94dc500c5535faab/src/controls/dev/CommonStyles/ToggleSwitch_themeresources.xaml#L188C20-L188C45) of 154 in its style, likely to accommodate the OnContent and OffContent values supported in WinUI. However, since .NET MAUI does not support displaying these contents, the default minimum width is unnecessary. As a result, the control always reserves that space, leading to unnecessary space usage in .NET MAUI. ### Description of Change - The native ToggleSwitch's minimum width is now set based on the MinimumWidthRequest value provided by the MAUI Switch view. Since MAUI does not support OnContent and OffContent, the default width is unnecessary. This change ensures the control's width reflects the actual layout requirement, resolving the unwanted spacing issue. ### Reference - [ToggleSwitchThemeMinWidth](https://github.com/microsoft/microsoft-ui-xaml/blob/a3021d80977fecc7d6ca33dc94dc500c5535faab/src/controls/dev/CommonStyles/ToggleSwitch_themeresources.xaml#L188C20-L188C45) - [DefaultSpacing](https://github.com/microsoft/microsoft-ui-xaml/blob/a3021d80977fecc7d6ca33dc94dc500c5535faab/src/controls/dev/CommonStyles/ToggleSwitch_themeresources.xaml#L501) ### Issues Fixed Fixes dotnet#28901 Fixes dotnet#30273 Fixes dotnet#10107 ### Tested the behaviour in the following platforms - [x] iOS - [x] Mac - [x] Android - [x] Windows ### Screenshot | Before Fix | After Fix | |----------|----------| | <video src="https://github.com/user-attachments/assets/d8f0c4da-1199-457f-8186-4bf80495c9c8"> | <video src="https://github.com/user-attachments/assets/8128cfbf-1aaf-46c9-a059-45e512114f73"> |
<!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! <!-- !!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING MAIN. !!!!!!! --> ### Root Cause of the issue - The native WinUI ToggleSwitch control defines a default [MinWidth](https://github.com/microsoft/microsoft-ui-xaml/blob/a3021d80977fecc7d6ca33dc94dc500c5535faab/src/controls/dev/CommonStyles/ToggleSwitch_themeresources.xaml#L188C20-L188C45) of 154 in its style, likely to accommodate the OnContent and OffContent values supported in WinUI. However, since .NET MAUI does not support displaying these contents, the default minimum width is unnecessary. As a result, the control always reserves that space, leading to unnecessary space usage in .NET MAUI. ### Description of Change - The native ToggleSwitch's minimum width is now set based on the MinimumWidthRequest value provided by the MAUI Switch view. Since MAUI does not support OnContent and OffContent, the default width is unnecessary. This change ensures the control's width reflects the actual layout requirement, resolving the unwanted spacing issue. ### Reference - [ToggleSwitchThemeMinWidth](https://github.com/microsoft/microsoft-ui-xaml/blob/a3021d80977fecc7d6ca33dc94dc500c5535faab/src/controls/dev/CommonStyles/ToggleSwitch_themeresources.xaml#L188C20-L188C45) - [DefaultSpacing](https://github.com/microsoft/microsoft-ui-xaml/blob/a3021d80977fecc7d6ca33dc94dc500c5535faab/src/controls/dev/CommonStyles/ToggleSwitch_themeresources.xaml#L501) ### Issues Fixed Fixes #28901 Fixes #30273 Fixes #10107 ### Tested the behaviour in the following platforms - [x] iOS - [x] Mac - [x] Android - [x] Windows ### Screenshot | Before Fix | After Fix | |----------|----------| | <video src="https://github.com/user-attachments/assets/d8f0c4da-1199-457f-8186-4bf80495c9c8"> | <video src="https://github.com/user-attachments/assets/8128cfbf-1aaf-46c9-a059-45e512114f73"> |
…sample on candidate (#34697) ### Details PR #30538 fixes the Windows Switch control width issue, where it previously reserved unnecessary space inherited from WinUI’s ToggleSwitch default style. Due to this change, we need to re-save the existing switch images. Also the reduced Switch width, the grid columns in AppThemePage are rebalanced, causing the RadioButton (which has Grid.ColumnSpan="2") to overlap the Editor control on the right side. ### Description of Change: - Before: RadioButton had Grid.ColumnSpan="2", causing it to span both columns and overlap the Editor in Column 1 of the same row. - After: RadioButton is constrained to Grid.Column="0" only, so the Editor in Column 1 remains in its own cell without overlap. ### Failures caused by these PRs: #30538 - The Switch previously occupied the full width; now it takes only the required space. #30089 - The Slider previously appeared without a background color, now the background color is applied correctly. ### Screenshots | Before Issue Fix | After Issue Fix | |----------|----------| | <img width="300" height="600" src="https://github.com/user-attachments/assets/ac70ad29-f055-4870-b9b2-5a381f601254"> | <img width="300" height="600" src="https://github.com/user-attachments/assets/a06482bf-c0de-4c27-87be-d9d00a503723"> |
Note
Are you waiting for the changes in this PR to be merged?
It would be very helpful if you could test the resulting artifacts from this PR and let us know in a comment if this change resolves your issue. Thank you!
Root Cause of the issue
Description of Change
Reference
Issues Fixed
Fixes #28901
Fixes #30273
Fixes #10107
Tested the behaviour in the following platforms
Screenshot
Before-Fix.mp4
After-Fix.mp4