About maui-theming
.NET MAUI applications ke liye theming guidance that explains OS-driven light and dark modes and custom runtime theme switching. It helps developers choose an approach and avoid platform-specific pitfalls.
Key features
- 01AppThemeBinding for OS light and dark modes
- 02ResourceDictionary-based custom themes
- 03Combining system and custom themes
- 04DynamicResource for runtime switching
- 05Android UiMode configuration guidance
Use cases
- 01Add automatic light and dark themes
- 02Switch between branded themes at runtime
- 03Prevent Android theme changes from restarting the activity
Install
Copy the command and run it in a terminal.
npx skills add https:/ / github.com/ davidortinau/ maui-skills --skill maui-themingAfter installing, type/maui-themingin Claude Code to confirm it loaded.
Bundled filesreferences/theming-api.md
Details
From the project README.NET MAUI Theming
Choosing your approach
| Approach | Best for | Limitation |
|---|---|---|
| AppThemeBinding | Auto light/dark with OS — minimal code | Only two themes (light + dark) |
| ResourceDictionary swap | Custom branded themes, >2 themes, user preference | More setup, must use DynamicResource everywhere |
| Both combined | Auto OS response + custom theme colors | Most flexible but most complex |
Critical gotchas
Android: ConfigChanges.UiMode is REQUIRED
MainActivity must include ConfigChanges.UiMode or theme change events will
not fire and the activity restarts instead of handling the change:
[Activity(Theme = "@style/Maui.SplashTheme",
MainLauncher = true,
ConfigurationChanges = ConfigChanges.ScreenSize
| ConfigChanges.Orientation
| ConfigChanges.UiMode // ← Required for theme detection
| ConfigChanges.ScreenLayout
| ConfigChanges.SmallestScreenSize
| ConfigChanges.Density)]
public class MainActivity : MauiAppCompatActivity { }
Without UiMode, toggling dark mode in Android settings causes a full activity
restart — losing navigation state and appearing as a crash to users.
CSS themes cannot be swapped at runtime
MAUI supports CSS styling, but CSS-based themes cannot be swapped dynamically. Use ResourceDictionary theming for runtime switching.
DynamicResource vs StaticResource
When using ResourceDictionary theme switching, you must use DynamicResource:
<!-- ✅ Updates when theme dictionary changes -->
<Label TextColor="{DynamicResource PrimaryTextColor}" />
<!-- ❌ Frozen at first load — won't update on theme switch -->
<Label TextColor="{StaticResource PrimaryTextColor}" />
Quick reference
- OS light/dark →
AppThemeBindingmarkup extension - Theme colors in C# →
SetAppThemeColor(),SetAppTheme<T>() - Read OS theme →
Application.Current.RequestedTheme - Force theme →
Application.Current.UserAppTheme = AppTheme.Dark - Theme changes →
RequestedThemeChangedevent - Custom switching → Swap
ResourceDictionaryinMergedDictionaries - Runtime bindings →
DynamicResource(notStaticResource)