Skip to main content
ClaudeWave
Skill429 estrellas del repoactualizado 10d ago

maui-theming

The maui-theming skill enables .NET MAUI developers to implement light and dark mode support, custom branded themes, and runtime theme switching using AppThemeBinding, ResourceDictionary swapping, and system theme detection. Use this skill when adding theme support to a MAUI app, creating custom color palettes, detecting system theme changes, or letting users select their preferred theme at runtime.

Instalar en Claude Code
Copiar
git clone --depth 1 https://github.com/managedcode/dotnet-skills /tmp/maui-theming && cp -r /tmp/maui-theming/catalog/Frameworks/Official-DotNet-MAUI/skills/maui-theming ~/.claude/skills/maui-theming
Después abre una sesión nueva de Claude Code; el skill carga automáticamente.

SKILL.md

# .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.

## 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.

### XAML

```xml
<Label Text="Themed text"
       TextColor="{AppThemeBinding Light=Green, Dark=Red}"
       BackgroundColor="{AppThemeBinding Light=White, Dark=Black}" />

<!-- With resource references -->
<Label TextColor="{AppThemeBinding Light={StaticResource LightPrimary},
                                   Dark={StaticResource DarkPrimary}}" />
```

### C# Extension Methods

```csharp
var label = new Label();

// Color-specific helper
label.SetAppThemeColor(Label.TextColorProperty, Colors.Green, Colors.Red);

// Generic helper for any bindable property type
label.SetAppTheme<Color>(Label.TextColorProperty, Colors.Green, Colors.Red);
```

## ResourceDictionary Theming (Custom Themes)

Use separate `ResourceDictionary` files with matching keys to define themes, then swap them at runtime.

### Step 1 — Define Theme Dictionaries

When using compiled XAML with `x:Class` (as shown below), each dictionary needs a code-behind that calls `InitializeComponent()`. Dictionaries loaded via `Source` without `x:Class` do not need code-behind.

**LightTheme.xaml**

```xml
<ResourceDictionary xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
                    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                    x:Class="MyApp.Themes.LightTheme">
    <Color x:Key="PageBackgroundColor">White</Color>
    <Color x:Key="PrimaryTextColor">#333333</Color>
    <Color x:Key="AccentColor">#2196F3</Color>
</ResourceDictionary>
```

**LightTheme.xaml.cs**

```csharp
namespace MyApp.Themes;

public partial class LightTheme : ResourceDictionary
{
    public LightTheme() => InitializeComponent();
}
```

Create a matching **DarkTheme.xaml / DarkTheme.xaml.cs** with the same keys and different values.

### Step 2 — Consume with DynamicResource

Use `DynamicResource` so values update when the dictionary is swapped at runtime:

```xml
<ContentPage BackgroundColor="{DynamicResource PageBackgroundColor}">
    <Label Text="Hello"
           TextColor="{DynamicResource PrimaryTextColor}" />
    <Button Text="Action"
            BackgroundColor="{DynamicResource AccentColor}" />
</ContentPage>
```

### Step 3 — Switch Themes at Runtime

```csharp
void ApplyTheme(ResourceDictionary theme)
{
    // Assumes theme dictionaries are the only merged dictionaries.
    // If your App.xaml merges non-theme dictionaries (e.g., converters),
    // move them to Application.Resources directly instead.
    var mergedDictionaries = Application.Current!.Resources.MergedDictionaries;
    mergedDictionaries.Clear();
    mergedDictionaries.Add(theme);
}

// Usage
ApplyTheme(new DarkTheme());
```

## System Theme Detection

### Read the Current Theme

```csharp
AppTheme currentTheme = Application.Current!.RequestedTheme;
// Returns AppTheme.Light, AppTheme.Dark, or AppTheme.Unspecified
```

### Override the System Theme

```csharp
// Force dark mode regardless of OS setting
Application.Current!.UserAppTheme = AppTheme.Dark;

// Reset to follow system theme
Application.Current!.UserAppTheme = AppTheme.Unspecified;
```

### React to Theme Changes

```csharp
Application.Current!.RequestedThemeChanged += (s, e) =>
{
    AppTheme newTheme = e.RequestedTheme;
    // Update UI or switch ResourceDictionaries
};
```

## Combini
aspnet-coreSkill

Build, debug, modernize, or review ASP.NET Core applications with correct hosting, middleware, security, configuration, logging, and deployment patterns on current .NET. USE FOR: working on ASP.NET Core apps, services, or middleware; changing auth, routing, configuration, hosting, or deployment behavior; deciding between ASP.NET Core sub-stacks. DO NOT USE FOR: unrelated stacks; generic tasks that do not need this specific guidance. INVOKES: inspect the repository context, edit targeted files, and run relevant build, test, lint, or validation commands when changes are made.

aspireSkill

Build, upgrade, and operate .NET Aspire 13.3.x application hosts with current CLI, AppHost, ServiceDefaults, integrations, dashboard, testing, and Azure deployment patterns for distributed apps. USE FOR: Aspire.AppHost.Sdk, Aspire.Hosting.*, DistributedApplication.CreateBuilder, WithReference, WaitFor, AddProject, AddRedis, AddPostgres, aspire run, aspire init, aspire. DO NOT USE FOR: unrelated stacks; generic tasks that do not need this specific guidance. INVOKES: inspect the repository context, edit targeted files, and run relevant build, test, lint, or validation commands when changes are made.

azure-functionsSkill

Build, review, or migrate Azure Functions in .NET with correct execution model, isolated worker setup, bindings, DI, and Durable Functions patterns. USE FOR: working on Azure Functions in .NET; migrating from the in-process model to the isolated worker model; adding Durable Functions, bindings, or host configuration. DO NOT USE FOR: unrelated stacks; generic tasks that do not need this specific guidance. INVOKES: inspect the repository context, edit targeted files, and run relevant build, test, lint, or validation commands when changes are made.

blazorSkill

Build and review Blazor applications across server, WebAssembly, web app, and hybrid scenarios with correct component design, state flow, rendering, and hosting choices. USE FOR: building interactive web UIs with C# instead of JavaScript; choosing between Server, WebAssembly, or Auto render modes; designing component hierarchies and state. DO NOT USE FOR: unrelated stacks; generic tasks that do not need this specific guidance. INVOKES: inspect the repository context, edit targeted files, and run relevant build, test, lint, or validation commands when changes are made.

entity-framework6Skill

Maintain or migrate EF6-based applications with realistic guidance on what to keep, what to modernize, and when EF Core is or is not the right next step. USE FOR: EF6 codebases; runtime versus ORM migration decisions; EDMX, code-first, ObjectContext, and legacy data-access review. DO NOT USE FOR: unrelated stacks; generic tasks that do not need this specific guidance. INVOKES: inspect the repository context, edit targeted files, and run relevant build, test, lint, or validation commands when changes are made.

entity-framework-coreSkill

Design, tune, or review EF Core data access with proper modeling, migrations, query translation, performance, and lifetime management for modern .NET applications. USE FOR: DbContext, migrations, model configuration, EF queries, tracking, loading, performance, transactions, and EF6 migration decisions. DO NOT USE FOR: unrelated stacks; generic tasks that do not need this specific guidance. INVOKES: inspect the repository context, edit targeted files, and run relevant build, test, lint, or validation commands when changes are made.

mauiSkill

Build, review, or migrate .NET MAUI applications across Android, iOS, macOS, and Windows with correct cross-platform UI, platform integration, and native packaging assumptions. USE FOR: working on cross-platform mobile or desktop UI in .NET MAUI; integrating device capabilities, navigation, or platform-specific code; migrating Xamarin.Forms or aligning. DO NOT USE FOR: unrelated stacks; generic tasks that do not need this specific guidance. INVOKES: inspect the repository context, edit targeted files, and run relevant build, test, lint, or validation commands when changes are made.

mlnetSkill

Use ML.NET to train, evaluate, or integrate machine-learning models into .NET applications with realistic data preparation, inference, and deployment expectations. USE FOR: ML.NET integration; local model training or retraining; inference pipelines, model loading, evaluation, and deployment review. DO NOT USE FOR: unrelated stacks; generic tasks that do not need this specific guidance. INVOKES: inspect the repository context, edit targeted files, and run relevant build, test, lint, or validation commands when changes are made.