/maui-theming
Guide for theming .NET MAUI apps — light/dark mode via AppThemeBinding, ResourceDictionary theme switching, DynamicResource bindings, system theme detection, and user theme preferences. Use when: "dark mode", "light mode", "theming", "AppThemeBinding", "theme switching",
$ npx -y skills add dotnet/skills --skill maui-theming --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/maui-theming
Context preview
The summary Claude sees to decide when to auto-load this skill.
Guide for theming .NET MAUI apps — light/dark mode via AppThemeBinding, ResourceDictionary theme switching, DynamicResource bindings, system theme detection, and user theme preferences. Use when: "dark mode", "light mode", "theming", "AppThemeBinding", "theme switching",
SKILL.md
maui-theming.SKILL.mdname: maui-theming
description: >-
Guide for theming .NET MAUI apps — light/dark mode via AppThemeBinding,
ResourceDictionary theme switching, DynamicResource bindings, system theme
detection, and user theme preferences.
Use when: "dark mode", "light mode", "theming", "AppThemeBinding",
"theme switching", "ResourceDictionary theme", "dynamic resources",
"system theme detection", "color scheme", "app theme", "DynamicResource".
Do not use for: localization or language switching (see .NET MAUI localization
documentation), accessibility visual adjustments (see .NET MAUI accessibility
documentation), app icons or splash screens (see .NET MAUI app icons
documentation), or Bootstrap-style class theming (see Plugin.Maui.BootstrapTheme
NuGet package).
license: MIT
.NET MAUI Theming
Apply light/dark mode support, custom branded themes, and runtime theme switching in .NET MAUI apps using AppThemeBinding, ResourceDictionary swapping, and system theme detection APIs.
When to Use
- Adding light and dark mode support to a .NET MAUI app
- Creating custom branded themes with ResourceDictionary
- Detecting and responding to system theme changes at runtime
- Letting users choose a preferred theme (light, dark, or system default)
- Combining OS-driven theme response with custom color palettes
When Not to Use
- Localization or language switching — see [.NET MAUI localization docs](https://learn.microsoft.com/dotnet/maui/fundamentals/localization)
- Accessibility-specific visual adjustments — see [.NET MAUI accessibility docs](https://learn.microsoft.com/dotnet/maui/fundamentals/accessibility)
- App icon or splash screen configuration — see [.NET MAUI app icon docs](https://learn.microsoft.com/dotnet/maui/user-interface/images/app-icons)
- Bootstrap-style class theming — see the `Plugin.Maui.BootstrapTheme` NuGet package
Inputs
- A .NET MAUI project targeting .NET 8 or later
- XAML pages or C# UI code that need theme-aware styling
Workflow
1. Detect the current theme approach in the project (AppThemeBinding, ResourceDictionary, or none). 2. Choose the appropriate strategy: AppThemeBinding for simple light/dark, ResourceDictionary swap for custom/multiple themes, or both combined. 3. Define theme resources — inline `AppThemeBinding` values or separate `ResourceDictionary` files with matching keys. 4. Replace hardcoded colors with `DynamicResource` bindings (or `AppThemeBinding` markup) throughout XAML pages. 5. Add system theme detection via `Application.Current.RequestedTheme` and the `RequestedThemeChanged` event. 6. Implement user preference persistence with `Preferences.Set` / `Preferences.Get` and apply on startup. 7. Verify Android `ConfigChanges.UiMode` is set on `MainActivity` to avoid activity restarts on theme change. 8. Test both light and dark themes on at least one target platform, confirming all UI elements respond correctly.
Rules That Change the Answer
Check these rules against the user's scenario, and apply **only** the ones that affect what they asked. `UiMode` and dictionary swapping matter for *runtime theme switching*; they are noise in a question about setting up `AppThemeBinding`.
**Answer narrowly, but completely.** Completeness means showing the code that implements *what you recommended* — not adding adjacent topics. If you recommend `DynamicResource`, show the dictionary swap that makes it update. If the user asks for light/dark colours in C#, show **both** `SetAppThemeColor` (colours) and the generic `SetAppTheme<T>` (any bindable property type), and prefer resource keys over scattered hardcoded colours. Do not tack on platform configuration the question didn't raise.
| Rule | Do this | Not this | Why | |---|---|---|---| | **Runtime-swapped values must be dynamic** | `{DynamicResource Key}` | `{StaticResource Key}` | `StaticResource` resolves once at load and never updates when dictionaries are swapped. | | **Android must declare `UiMode`** *(only for runtime/system theme switching)* | Include `ConfigChanges.UiMode` in the `ConfigurationChanges` list on `MainActivity` | Omitting it | Without it Android restarts the activity on theme change — navigation state is lost and it looks like a crash. Irrelevant to a static `AppThemeBinding` setup | | **Force a theme via `UserAppTheme`** | `Application.Current.UserAppTheme = AppTheme.Dark` | Manually re-assigning colors | `UserAppTheme` overrides the OS; `AppTheme.Unspecified` returns to following the system. |
**Do not** replace a working `AppThemeBinding` setup with ResourceDictionary swapping (or vice versa) unless the user needs what the other approach provides — more than two themes, or a user-selectable theme.
Choosing an Approach
| Approach | Best for | Limitation | |----------|----------|------------| | **AppThemeBinding** | Automatic light/dark with OS — minimal code | Only two themes (light + dark) | | **ResourceDictionary swap** | Custom branded themes, more than two themes, user preference | More setup; must use `DynamicResource` everywhere | | **Both combined** | OS-driven response plus custom theme colors | Most flexible but most complex |
AppThemeBinding (OS Light/Dark)
`AppThemeBinding` selects a value based on the current system theme. It supports `Light`, `Dark`, and an optional `Default` fallback.
Define the palette once — don't scatter literals
Putting `{AppThemeBinding Light=#333333, Dark=#FFFFFF}` on every element is the single most common theming mistake: the palette ends up duplicated across dozens of files and cannot be changed in one place. **Recommend this shape as the final answer**, not inline literals:
<!-- App.xaml — one source of truth for the whole app -->
<Application.Resources>
<ResourceDictionary>
<!-- 1. Raw palette -->
<Color x:Key="LightPageBackground">#FFFFFF</Color>
<Color x:Key="DarkPageBackground">#1E1E1E</Color>
<Color x:Key="LightPrimaryText">#333333</Color>
<Color x:KRead more
name: maui-theming description: >- Guide for theming .NET MAUI apps — light/dark mode via AppThemeBinding, ResourceDictionary theme switching, DynamicResource bindings, system theme detection, and user theme preferences. Use when: "dark mode", "light mode", "theming", "AppThemeBinding", "theme switching", "ResourceDictionary theme", "dynamic resources", "system theme detection", "color scheme", "app theme", "DynamicResource". Do not use for: localization or language switching (see .NET MAUI localization documentation), accessibility visual adjustments (see .NET MAUI accessibility documentation), app icons or splash screens (see .NET MAUI app icons documentation), or Bootstrap-style class theming (see Plugin.Maui.BootstrapTheme NuGet package). license: MIT
.NET MAUI Theming
Apply light/dark mode support, custom branded themes, and runtime theme switching in .NET MAUI apps using AppThemeBinding, ResourceDictionary swapping, and system theme detection APIs.
When to Use
- Adding light and dark mode support to a .NET MAUI app
- Creating custom branded themes with ResourceDictionary
- Detecting and responding to system theme changes at runtime
- Letting users choose a preferred theme (light, dark, or system default)
- Combining OS-driven theme response with custom color palettes
When Not to Use
- Localization or language switching — see [.NET MAUI localization docs](https://learn.microsoft.com/dotnet/maui/fundamentals/localization)
- Accessibility-specific visual adjustments — see [.NET MAUI accessibility docs](https://learn.microsoft.com/dotnet/maui/fundamentals/accessibility)
- App icon or splash screen configuration — see [.NET MAUI app icon docs](https://learn.microsoft.com/dotnet/maui/user-interface/images/app-icons)
- Bootstrap-style class theming — see the `Plugin.Maui.BootstrapTheme` NuGet package
Inputs
- A .NET MAUI project targeting .NET 8 or later
- XAML pages or C# UI code that need theme-aware styling
Workflow
1. Detect the current theme approach in the project (AppThemeBinding, ResourceDictionary, or none). 2. Choose the appropriate strategy: AppThemeBinding for simple light/dark, ResourceDictionary swap for custom/multiple themes, or both combined. 3. Define theme resources — inline `AppThemeBinding` values or separate `ResourceDictionary` files with matching keys. 4. Replace hardcoded colors with `DynamicResource` bindings (or `AppThemeBinding` markup) throughout XAML pages. 5. Add system theme detection via `Application.Current.RequestedTheme` and the `RequestedThemeChanged` event. 6. Implement user preference persistence with `Preferences.Set` / `Preferences.Get` and apply on startup. 7. Verify Android `ConfigChanges.UiMode` is set on `MainActivity` to avoid activity restarts on theme change. 8. Test both light and dark themes on at least one target platform, confirming all UI elements respond correctly.
Rules That Change the Answer
Check these rules against the user's scenario, and apply **only** the ones that affect what they asked. `UiMode` and dictionary swapping matter for *runtime theme switching*; they are noise in a question about setting up `AppThemeBinding`.
**Answer narrowly, but completely.** Completeness means showing the code that implements *what you recommended* — not adding adjacent topics. If you recommend `DynamicResource`, show the dictionary swap that makes it update. If the user asks for light/dark colours in C#, show **both** `SetAppThemeColor` (colours) and the generic `SetAppTheme<T>` (any bindable property type), and prefer resource keys over scattered hardcoded colours. Do not tack on platform configuration the question didn't raise.
| Rule | Do this | Not this | Why | |---|---|---|---| | **Runtime-swapped values must be dynamic** | `{DynamicResource Key}` | `{StaticResource Key}` | `StaticResource` resolves once at load and never updates when dictionaries are swapped. | | **Android must declare `UiMode`** *(only for runtime/system theme switching)* | Include `ConfigChanges.UiMode` in the `ConfigurationChanges` list on `MainActivity` | Omitting it | Without it Android restarts the activity on theme change — navigation state is lost and it looks like a crash. Irrelevant to a static `AppThemeBinding` setup | | **Force a theme via `UserAppTheme`** | `Application.Current.UserAppTheme = AppTheme.Dark` | Manually re-assigning colors | `UserAppTheme` overrides the OS; `AppTheme.Unspecified` returns to following the system. |
**Do not** replace a working `AppThemeBinding` setup with ResourceDictionary swapping (or vice versa) unless the user needs what the other approach provides — more than two themes, or a user-selectable theme.
Choosing an Approach
| Approach | Best for | Limitation | |----------|----------|------------| | **AppThemeBinding** | Automatic light/dark with OS — minimal code | Only two themes (light + dark) | | **ResourceDictionary swap** | Custom branded themes, more than two themes, user preference | More setup; must use `DynamicResource` everywhere | | **Both combined** | OS-driven response plus custom theme colors | Most flexible but most complex |
AppThemeBinding (OS Light/Dark)
`AppThemeBinding` selects a value based on the current system theme. It supports `Light`, `Dark`, and an optional `Default` fallback.
Define the palette once — don't scatter literals
Putting `{AppThemeBinding Light=#333333, Dark=#FFFFFF}` on every element is the single most common theming mistake: the palette ends up duplicated across dozens of files and cannot be changed in one place. **Recommend this shape as the final answer**, not inline literals:
<!-- App.xaml — one source of truth for the whole app -->
<Application.Resources>
<ResourceDictionary>
<!-- 1. Raw palette -->
<Color x:Key="LightPageBackground">#FFFFFF</Color>
<Color x:Key="DarkPageBackground">#1E1E1E</Color>
<Color x:Key="LightPrimaryText">#333333</Color>
<Color x:KThis repository contains the .NET team's curated set of core skills and custom agents for coding agents. For information about the Agent Skills standard, see agentskills.io. 📊 Dashboard - Accuracy and efficiency scoring trends for contained plugins (
Repo: dotnet/skills
Other skills on dotnet-skills.
- /csharp-scripts
Run file-based C# apps with the .NET CLI when the user explicitly wants C#/.NET code without creating a project. Use for C# language/API experiments, one-file C# apps, small multi-file C# apps composed with `#:include`/`#:exclude`, or C# file-based apps linked with `#:ref`. Do
Open skill - /dotnet-pinvoke
Correctly call native (C/C++) libraries from .NET using P/Invoke and LibraryImport. Covers function signatures, string marshalling, memory lifetime, SafeHandle, and cross-platform patterns. USE FOR: writing new P/Invoke or LibraryImport declarations, reviewing or debugging
Open skill - /nuget-trusted-publishing
Set up NuGet trusted publishing (OIDC) on a GitHub Actions repo — replaces long-lived API keys with short-lived tokens. USE FOR: trusted publishing, NuGet OIDC, keyless NuGet publish, migrate from NuGet API key, NuGet/login, secure NuGet publishing. DO NOT USE FOR: publishing to
Open skill - /technology-selection
Guides technology selection and implementation of AI and ML features in .NET 8+ applications using ML.NET, Microsoft.Extensions.AI (MEAI), Microsoft Agent Framework (MAF), GitHub Copilot SDK, ONNX Runtime, and OllamaSharp. Covers the full spectrum from classic ML through modern
Open skill - /configuring-opentelemetry-dotnet
Configure OpenTelemetry distributed tracing, metrics, and logging in ASP.NET Core using the .NET OpenTelemetry SDK. Use when adding observability, setting up OTLP exporters, creating custom metrics/spans, or troubleshooting distributed trace correlation.
Open skill - /convert-blazor-server-to-webapp
Guides conversion of a pre-.NET 8 Blazor Server app into a .NET 8+ Blazor Web App. USE FOR: migrating apps that use AddServerSideBlazor and MapBlazorHub to the AddRazorComponents/MapRazorComponents model, converting _Host.cshtml to an App.razor root component, replacing
Open skill

