How did we discover the .NET MAUI Windows Switch styling issue?
During a recent project for a global logistics provider, we were tasked with modernizing their legacy fleet management desktop software into a unified, cross-platform application using .NET MAUI. The system is deployed across hundreds of Windows terminals at distribution centers, requiring a high-contrast, custom-branded UI theme to improve visibility for warehouse operators.
While refining the configuration screens, our QA team flagged a recurring UI inconsistency. We realized that the standard .NET MAUI Switch control (which translates to ToggleSwitch on Windows) was exhibiting erratic background coloring. Specifically, when the switch was in a disabled OFF state or when a user hovered over it in an enabled OFF state, the control ignored our custom color scheme and reverted to a washed-out, bright white background. In a predominantly dark-themed interface, this glitch was jarring and confusing for users.
When organizations hire software developer teams for cross-platform overhauls, the expectation is absolute parity and polish across target operating systems. This seemingly minor visual bug highlighted the complex interaction between .NET MAUI abstractions and native WinUI 3 rendering. This challenge inspired this article so other engineering teams can avoid the pitfalls of native control state management in .NET MAUI.
What is the business context behind the ToggleSwitch background problem?
The enterprise application allows logistics managers to toggle various hardware sensors and notification rules for their fleets. Many of these toggles are conditionally disabled based on user permissions or active system states. A clear visual distinction between enabled, disabled and interactive (hover) states is critical for operational efficiency.
In our .NET MAUI architecture, we relied on the default Switch control. We expected the following behavior for the OFF state:
- OFF (enabled): Standard gray background.
- OFF (hover/PointerOver): Darker gray background for interactive feedback.
- OFF (disabled): Light gray background indicating inactivity, with no white fading.
Instead, we encountered the following issues on Windows:
Case 1: When IsToggled="False" and IsEnabled="False", the actual background rendered as a washed-out white instead of the expected light gray.
Case 2: When IsToggled="False" and IsEnabled="True", hovering over the control (PointerOver) caused an unexpected white background to appear instead of a slightly darker gray.
Why did the SwitchHandler override fail to fix the white background?
Our initial diagnostic step was to intercept the native control mapping using a .NET MAUI Handler. We attempted to inject WinUI lightweight styling keys directly into the platformView.Resources dictionary.
public class CustomSwitchHandler : SwitchHandler
{
protected override void ConnectHandler(ToggleSwitch platformView)
{
base.ConnectHandler(platformView);
platformView.Resources["ToggleSwitchFillOff"] =
new Microsoft.UI.Xaml.Media.SolidColorBrush(Microsoft.UI.Colors.Gray);
platformView.Resources["ToggleSwitchFillOffPointerOver"] =
new Microsoft.UI.Xaml.Media.SolidColorBrush(Microsoft.UI.Colors.DarkGray);
platformView.Resources["ToggleSwitchFillOffDisabled"] =
new Microsoft.UI.Xaml.Media.SolidColorBrush(Microsoft.UI.Colors.LightGray);
}
}
Despite this logical approach, it failed. The symptoms persisted. But why? The root cause lies in how and when WinUI 3 evaluates visual states and resource dictionaries.
When you manipulate platformView.Resources inside the ConnectHandler method, you are attempting to append resources to the instance of the control after the initial WinUI ControlTemplate has been resolved. Furthermore, when a user hovers over the switch, the WinUI VisualStateManager transitions to the “PointerOver” state. During this transition, the native control looks up the styling keys hierarchy. Due to internal template bindings in WinUI’s generic.xaml, the locally injected handler resources are often bypassed or overwritten by the active theme’s defaults. This results in the control falling back to the default white/light theme colors hardcoded in the Windows SDK.
What alternative solutions did we consider for .NET MAUI styling?
For companies looking to hire dotnet developers for enterprise modernization, understanding the tradeoffs between different UI abstraction layers is essential. We evaluated several approaches to resolve this.
Can we use MAUI VisualStateManager to fix the hover state?
We first looked at keeping the solution entirely within cross-platform XAML using MAUI’s VisualStateManager. However, we quickly realized that while MAUI supports Normal and Disabled states, it does not natively expose a robust PointerOver (hover) visual state for the Switch control across all platforms. Relying on MAUI’s VSM would require complex custom behaviors and wouldn’t neatly solve the native WinUI rendering quirks.
Should we override the WinUI ControlTemplate entirely?
Another option was to extract the entire default ControlTemplate for the ToggleSwitch from the WinUI generic.xaml and maintain our own custom template in the Windows platform folder. While this guarantees 100% control over every pixel, it introduces a significant maintenance burden. If Microsoft updates the internal structure or accessibility features of the ToggleSwitch in a future WinUI release, our custom template would become stale and potentially break.
How does native WinUI lightweight styling solve the issue?
We concluded that the most robust solution was to utilize Native WinUI Lightweight Styling correctly. Instead of injecting resources at the control instance level via Handlers, we needed to define these styling keys at the application or window level natively in the Windows platform project. This ensures the WinUI VisualStateManager finds our custom brushes before it falls back to the OS defaults during state transitions.
How to correctly implement WinUI lightweight styling for ToggleSwitch?
To prevent the unexpected white background, we moved the styling rules out of the C# Handler and into the native Windows application resources. By defining the resources in Platforms/Windows/App.xaml, we ensured they were globally available to all ToggleSwitch instances in the native visual tree.
Here is the exact implementation we used to achieve the desired gray states:
<!-- Platforms/Windows/App.xaml -->
<maui:MauiWinUIApplication
x:Class="OurEnterpriseApp.WinUI.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:maui="using:Microsoft.Maui"
xmlns:local="using:OurEnterpriseApp.WinUI">
<maui:MauiWinUIApplication.Resources>
<ResourceDictionary>
<ResourceDictionary.ThemeDictionaries>
<!-- Apply to both Default and Dark themes if necessary -->
<ResourceDictionary x:Key="Default">
<!-- OFF (enabled) background -->
<SolidColorBrush x:Key="ToggleSwitchFillOff" Color="Gray" />
<!-- OFF (hover) background -->
<SolidColorBrush x:Key="ToggleSwitchFillOffPointerOver" Color="DarkGray" />
<!-- OFF (disabled) background -->
<SolidColorBrush x:Key="ToggleSwitchFillOffDisabled" Color="LightGray" />
<!-- Also override the stroke/border to prevent white borders -->
<SolidColorBrush x:Key="ToggleSwitchStrokeOff" Color="Gray" />
<SolidColorBrush x:Key="ToggleSwitchStrokeOffPointerOver" Color="DarkGray" />
<SolidColorBrush x:Key="ToggleSwitchStrokeOffDisabled" Color="LightGray" />
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
</ResourceDictionary>
</maui:MauiWinUIApplication.Resources>
</maui:MauiWinUIApplication>
Validation Steps:
- We verified that toggling the switch maintained the expected active colors.
- We simulated a disabled state (
IsEnabled="False") and the control cleanly rendered theLightGraybrush without any washed-out white overlays. - We performed mouse-over tests on enabled switches, confirming the smooth transition to
DarkGraywithout intermediate white flashing. - We toggled between Windows Light and Dark OS themes to ensure the
ThemeDictionariesapplication behaved as expected.
What are the key lessons for engineering teams building cross-platform apps?
When you hire app developer to create a mobile app or cross-platform desktop tool, understanding the underlying native rendering engines is what separates a mediocre app from a robust enterprise tool. Here are the actionable insights from this challenge:
- Abstractions have limits: Cross-platform frameworks like .NET MAUI provide excellent productivity, but native platform quirks (like WinUI’s visual state management) will inevitably surface.
- Understand resource resolution: Injecting resources programmatically via Handlers is subject to timing and template-binding limitations. Application-level XAML dictionaries offer a much more reliable fallback mechanism for native styling.
- Leverage lightweight styling: Before overriding entire ControlTemplates, always check if the native platform (iOS, Android, Windows) offers lightweight styling keys. It is safer and more maintainable.
- Test non-default states early: UI testing often focuses on the “happy path” (Normal state). Hover, Pressed, Disabled and Focused states must be audited across all operating systems.
- Respect the native VisualStateManager: MAUI’s VSM and WinUI’s VSM operate at different layers. For platform-specific interactions like mouse hover, native VSM configuration is often required.
How can we wrap up this .NET MAUI styling challenge?
Achieving visual consistency across Windows, iOS and Android requires more than just standard .NET MAUI properties. By shifting our approach from custom C# Handlers to native WinUI lightweight styling in App.xaml, we eliminated the jarring white backgrounds on the ToggleSwitch during disabled and hover states. This solution preserved the integrity of our logistics client’s UI theme while maintaining future compatibility with framework updates. If your team is navigating complex cross-platform UI modernization, contact us to explore how our specialized engineering teams can help.
Social Hashtags
#DotNETMAUI #DotNET #WinUI3 #WindowsDevelopment #CrossPlatformDevelopment #AppDevelopment #CSharp #XAML #SoftwareDevelopment #DotNETDeveloper #WindowsApp #UIDevelopment
Frequently Asked Questions
.NET MAUI aims to use the most natural native control for each platform. On iOS, it uses UISwitch. On Android, it uses SwitchCompat. On Windows (WinUI 3), the ToggleSwitch provides the most authentic desktop experience for boolean toggles.
Yes. WinUI provides specific keys for the switch thumb, such as ToggleSwitchKnobFillOff and ToggleSwitchKnobFillOn. You can override these in the same App.xaml resource dictionary.
No. By placing the XAML inside the Platforms/Windows/App.xaml directory, the .NET MAUI build system ensures these resources are only compiled and applied when targeting the Windows operating system.
.NET MAUI abstracts common visual states (Normal, Disabled, PointerOver). However, control-specific implementations vary. The Switch control abstraction historically prioritizes touch environments (iOS/Android) where "hover" does not exist, leading to gaps in desktop-specific pointer transitions.
Yes, but it must be done carefully. Instead of modifying platformView.Resources in the handler, you can modify the application-level resources using native WinUI APIs in the MAUI Windows startup lifecycle, though XAML remains the recommended and cleaner approach.
Success Stories That Inspire
See how our team takes complex business challenges and turns them into powerful, scalable digital solutions. From custom software and web applications to automation, integrations, and cloud-ready systems, each project reflects our commitment to innovation, performance, and long-term value.

California-based SMB Hired Dedicated Developers to Build a Photography SaaS Platform

Swedish Agency Built a Laravel-Based Staffing System by Hiring a Dedicated Remote Team

















