From maui-skills
Guides .NET MAUI app theming with light/dark modes, AppThemeBinding, dynamic resources, ResourceDictionary switching, and system theme detection.
npx claudepluginhub davidortinau/maui-skills --plugin maui-skillsThis skill uses the workspace's default tool permissions.
| Approach | Best for | Limitation |
Implements light/dark mode theming in .NET MAUI apps using AppThemeBinding, ResourceDictionary switching, DynamicResource bindings, system theme detection, and user preferences.
Guides .NET MAUI app localization using .resx files, runtime culture switching, RTL layouts, platform declarations (Info.plist, appxmanifest), and image strategies. Use for multi-language support.
Manages WPF Style definitions and ResourceDictionary patterns including BasedOn inheritance and resource merging. Use when building theme systems, organizing resources, or choosing between StaticResource and DynamicResource.
Share bugs, ideas, or general feedback.
| 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 |
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.
MAUI supports CSS styling, but CSS-based themes cannot be swapped dynamically. Use ResourceDictionary theming for runtime switching.
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}" />
AppThemeBinding markup extensionSetAppThemeColor(), SetAppTheme<T>()Application.Current.RequestedThemeApplication.Current.UserAppTheme = AppTheme.DarkRequestedThemeChanged eventResourceDictionary in MergedDictionariesDynamicResource (not StaticResource)