[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-dotnet-maui-theming":3,"mdc--2qeknj-key":37,"related-org-dotnet-maui-theming":2899,"related-repo-dotnet-maui-theming":3063},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":11,"stars":25,"repoUrl":26,"updatedAt":27,"license":28,"forks":29,"topics":30,"repo":32,"sourceUrl":35,"mdContent":36},"maui-theming","theme .NET MAUI applications","Guide for theming .NET MAUI apps — light\u002Fdark 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).",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},"dotnet",".NET (Microsoft)","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Fdotnet.png",[12,16,19,22],{"name":13,"slug":14,"type":15},"MAUI","maui","tag",{"name":17,"slug":18,"type":15},".NET","net",{"name":20,"slug":21,"type":15},"Mobile","mobile",{"name":23,"slug":24,"type":15},"Themes","themes",4576,"https:\u002F\u002Fgithub.com\u002Fdotnet\u002Fskills","2026-08-01T05:42:26.183428","MIT",332,[31],"agent-skills",{"repoUrl":26,"stars":25,"forks":29,"topics":33,"description":34},[31],"Repository for skills to assist AI coding agents with .NET and C#","https:\u002F\u002Fgithub.com\u002Fdotnet\u002Fskills\u002Ftree\u002FHEAD\u002Fplugins\u002Fdotnet-maui\u002Fskills\u002Fmaui-theming","---\nname: maui-theming\ndescription: >-\n  Guide for theming .NET MAUI apps — light\u002Fdark mode via AppThemeBinding,\n  ResourceDictionary theme switching, DynamicResource bindings, system theme\n  detection, and user theme preferences.\n  Use when: \"dark mode\", \"light mode\", \"theming\", \"AppThemeBinding\",\n  \"theme switching\", \"ResourceDictionary theme\", \"dynamic resources\",\n  \"system theme detection\", \"color scheme\", \"app theme\", \"DynamicResource\".\n  Do not use for: localization or language switching (see .NET MAUI localization\n  documentation), accessibility visual adjustments (see .NET MAUI accessibility\n  documentation), app icons or splash screens (see .NET MAUI app icons\n  documentation), or Bootstrap-style class theming (see Plugin.Maui.BootstrapTheme\n  NuGet package).\nlicense: MIT\n---\n\n# .NET MAUI Theming\n\nApply light\u002Fdark mode support, custom branded themes, and runtime theme switching in .NET MAUI apps using AppThemeBinding, ResourceDictionary swapping, and system theme detection APIs.\n\n## When to Use\n\n- Adding light and dark mode support to a .NET MAUI app\n- Creating custom branded themes with ResourceDictionary\n- Detecting and responding to system theme changes at runtime\n- Letting users choose a preferred theme (light, dark, or system default)\n- Combining OS-driven theme response with custom color palettes\n\n## When Not to Use\n\n- Localization or language switching — see [.NET MAUI localization docs](https:\u002F\u002Flearn.microsoft.com\u002Fdotnet\u002Fmaui\u002Ffundamentals\u002Flocalization)\n- Accessibility-specific visual adjustments — see [.NET MAUI accessibility docs](https:\u002F\u002Flearn.microsoft.com\u002Fdotnet\u002Fmaui\u002Ffundamentals\u002Faccessibility)\n- App icon or splash screen configuration — see [.NET MAUI app icon docs](https:\u002F\u002Flearn.microsoft.com\u002Fdotnet\u002Fmaui\u002Fuser-interface\u002Fimages\u002Fapp-icons)\n- Bootstrap-style class theming — see the `Plugin.Maui.BootstrapTheme` NuGet package\n\n## Inputs\n\n- A .NET MAUI project targeting .NET 8 or later\n- XAML pages or C# UI code that need theme-aware styling\n\n## Workflow\n\n1. Detect the current theme approach in the project (AppThemeBinding, ResourceDictionary, or none).\n2. Choose the appropriate strategy: AppThemeBinding for simple light\u002Fdark, ResourceDictionary swap for custom\u002Fmultiple themes, or both combined.\n3. Define theme resources — inline `AppThemeBinding` values or separate `ResourceDictionary` files with matching keys.\n4. Replace hardcoded colors with `DynamicResource` bindings (or `AppThemeBinding` markup) throughout XAML pages.\n5. Add system theme detection via `Application.Current.RequestedTheme` and the `RequestedThemeChanged` event.\n6. Implement user preference persistence with `Preferences.Set` \u002F `Preferences.Get` and apply on startup.\n7. Verify Android `ConfigChanges.UiMode` is set on `MainActivity` to avoid activity restarts on theme change.\n8. Test both light and dark themes on at least one target platform, confirming all UI elements respond correctly.\n\n## Rules That Change the Answer\n\nCheck these rules against the user's scenario, and apply **only** the ones that\naffect what they asked. `UiMode` and dictionary swapping matter for *runtime theme\nswitching*; they are noise in a question about setting up `AppThemeBinding`.\n\n**Answer narrowly, but completely.** Completeness means showing the code that\nimplements *what you recommended* — not adding adjacent topics. If you recommend\n`DynamicResource`, show the dictionary swap that makes it update. If the user asks\nfor light\u002Fdark colours in C#, show **both** `SetAppThemeColor` (colours) and the\ngeneric `SetAppTheme\u003CT>` (any bindable property type), and prefer resource keys over\nscattered hardcoded colours. Do not tack on platform configuration the question\ndidn't raise.\n\n| Rule | Do this | Not this | Why |\n|---|---|---|---|\n| **Runtime-swapped values must be dynamic** | `{DynamicResource Key}` | `{StaticResource Key}` | `StaticResource` resolves once at load and never updates when dictionaries are swapped. |\n| **Android must declare `UiMode`** *(only for runtime\u002Fsystem 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 |\n| **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. |\n\n**Do not** replace a working `AppThemeBinding` setup with ResourceDictionary\nswapping (or vice versa) unless the user needs what the other approach provides —\nmore than two themes, or a user-selectable theme.\n\n## Choosing an Approach\n\n| Approach | Best for | Limitation |\n|----------|----------|------------|\n| **AppThemeBinding** | Automatic light\u002Fdark with OS — minimal code | Only two themes (light + dark) |\n| **ResourceDictionary swap** | Custom branded themes, more than two themes, user preference | More setup; must use `DynamicResource` everywhere |\n| **Both combined** | OS-driven response plus custom theme colors | Most flexible but most complex |\n\n## AppThemeBinding (OS Light\u002FDark)\n\n`AppThemeBinding` selects a value based on the current system theme. It supports `Light`, `Dark`, and an optional `Default` fallback.\n\n### Define the palette once — don't scatter literals\n\nPutting `{AppThemeBinding Light=#333333, Dark=#FFFFFF}` on every element is the\nsingle most common theming mistake: the palette ends up duplicated across dozens of\nfiles and cannot be changed in one place. **Recommend this shape as the final\nanswer**, not inline literals:\n\n```xml\n\u003C!-- App.xaml — one source of truth for the whole app -->\n\u003CApplication.Resources>\n    \u003CResourceDictionary>\n\n        \u003C!-- 1. Raw palette -->\n        \u003CColor x:Key=\"LightPageBackground\">#FFFFFF\u003C\u002FColor>\n        \u003CColor x:Key=\"DarkPageBackground\">#1E1E1E\u003C\u002FColor>\n        \u003CColor x:Key=\"LightPrimaryText\">#333333\u003C\u002FColor>\n        \u003CColor x:Key=\"DarkPrimaryText\">#E0E0E0\u003C\u002FColor>\n\n        \u003C!-- 2. Implicit styles bind the pair once; every page inherits them -->\n        \u003CStyle TargetType=\"ContentPage\" ApplyToDerivedTypes=\"True\">\n            \u003CSetter Property=\"BackgroundColor\"\n                    Value=\"{AppThemeBinding Light={StaticResource LightPageBackground},\n                                            Dark={StaticResource DarkPageBackground}}\" \u002F>\n        \u003C\u002FStyle>\n\n        \u003CStyle TargetType=\"Label\">\n            \u003CSetter Property=\"TextColor\"\n                    Value=\"{AppThemeBinding Light={StaticResource LightPrimaryText},\n                                            Dark={StaticResource DarkPrimaryText}}\" \u002F>\n        \u003C\u002FStyle>\n\n    \u003C\u002FResourceDictionary>\n\u003C\u002FApplication.Resources>\n```\n\nPages then need **no theming markup at all** — they pick the styles up implicitly.\nUse an inline `AppThemeBinding` only for genuine one-offs, and even then reference\n`{StaticResource}` keys rather than literal hex.\n\n### XAML (inline form, for one-offs)\n\n```xml\n\u003CLabel Text=\"Themed text\"\n       TextColor=\"{AppThemeBinding Light=Green, Dark=Red}\"\n       BackgroundColor=\"{AppThemeBinding Light=White, Dark=Black}\" \u002F>\n\n\u003C!-- With resource references — preferred over literals -->\n\u003CLabel TextColor=\"{AppThemeBinding Light={StaticResource LightPrimary},\n                                   Dark={StaticResource DarkPrimary}}\" \u002F>\n```\n\n### C# Extension Methods\n\nShow **both** when answering a \"light\u002Fdark colours in C#\" question — `SetAppThemeColor`\ncovers `Color` properties, `SetAppTheme\u003CT>` covers everything else:\n\n```csharp\nvar label = new Label();\n\n\u002F\u002F Color-specific helper\nlabel.SetAppThemeColor(Label.TextColorProperty, Colors.Green, Colors.Red);\n\n\u002F\u002F Generic helper — works for any bindable property type, not just Color\nlabel.SetAppTheme\u003CColor>(Label.TextColorProperty, Colors.Green, Colors.Red);\nlabel.SetAppTheme\u003Cdouble>(Label.FontSizeProperty, 14, 16);\n\n\u002F\u002F The BindableProperty must belong to the object you call it on —\n\u002F\u002F Image.SourceProperty goes on an Image, not a Label.\nvar image = new Image();\nimage.SetAppTheme\u003CImageSource>(Image.SourceProperty,\n    ImageSource.FromFile(\"logo_light.png\"),\n    ImageSource.FromFile(\"logo_dark.png\"));\n```\n\nPrefer defining the values as resource keys and referencing them, rather than\nscattering hardcoded colours across the codebase.\n\n## ResourceDictionary Theming (Custom Themes)\n\nUse separate `ResourceDictionary` files with matching keys to define themes, then swap them at runtime.\n\n### Step 1 — Define Theme Dictionaries\n\nWhen 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.\n\n**LightTheme.xaml**\n\n```xml\n\u003CResourceDictionary xmlns=\"http:\u002F\u002Fschemas.microsoft.com\u002Fdotnet\u002F2021\u002Fmaui\"\n                    xmlns:x=\"http:\u002F\u002Fschemas.microsoft.com\u002Fwinfx\u002F2009\u002Fxaml\"\n                    x:Class=\"MyApp.Themes.LightTheme\">\n    \u003CColor x:Key=\"PageBackgroundColor\">White\u003C\u002FColor>\n    \u003CColor x:Key=\"PrimaryTextColor\">#333333\u003C\u002FColor>\n    \u003CColor x:Key=\"AccentColor\">#2196F3\u003C\u002FColor>\n\u003C\u002FResourceDictionary>\n```\n\n**LightTheme.xaml.cs**\n\n```csharp\nnamespace MyApp.Themes;\n\npublic partial class LightTheme : ResourceDictionary\n{\n    public LightTheme() => InitializeComponent();\n}\n```\n\nCreate a matching **DarkTheme.xaml \u002F DarkTheme.xaml.cs** with the same keys and different values.\n\n### Step 2 — Consume with DynamicResource\n\nUse `DynamicResource` so values update when the dictionary is swapped at runtime:\n\n```xml\n\u003CContentPage BackgroundColor=\"{DynamicResource PageBackgroundColor}\">\n    \u003CLabel Text=\"Hello\"\n           TextColor=\"{DynamicResource PrimaryTextColor}\" \u002F>\n    \u003CButton Text=\"Action\"\n            BackgroundColor=\"{DynamicResource AccentColor}\" \u002F>\n\u003C\u002FContentPage>\n```\n\n### Step 3 — Switch Themes at Runtime\n\n> 🚨 **Never call `MergedDictionaries.Clear()` to swap a theme.** The default MAUI\n> template merges `Resources\u002FStyles\u002FColors.xaml` and `Styles.xaml` into\n> `Application.Resources`. `Clear()` removes **those too**, so every implicit style,\n> brush and colour in the app silently disappears — buttons, entries and labels all\n> revert to unstyled defaults. Verified: after `Clear()`, `MergedDictionaries` drops\n> from 2 to 1 and the template's `Primary` colour no longer resolves.\n\nRemove only the theme you added, and leave everything else alone:\n\n```csharp\nstatic ResourceDictionary? _currentTheme;\n\nvoid ApplyTheme(ResourceDictionary theme)\n{\n    var merged = Application.Current!.Resources.MergedDictionaries;\n\n    \u002F\u002F ✅ Remove ONLY the previous theme — Colors.xaml \u002F Styles.xaml survive\n    if (_currentTheme is not null)\n        merged.Remove(_currentTheme);\n\n    merged.Add(theme);\n    _currentTheme = theme;\n}\n\n\u002F\u002F Usage\nApplyTheme(new DarkTheme());\n```\n\n```csharp\n\u002F\u002F ❌ Destroys the app's Colors.xaml and Styles.xaml along with the old theme\nvar merged = Application.Current!.Resources.MergedDictionaries;\nmerged.Clear();\nmerged.Add(theme);\n```\n\n## System Theme Detection\n\n### Read the Current Theme\n\n```csharp\nAppTheme currentTheme = Application.Current!.RequestedTheme;\n\u002F\u002F Returns AppTheme.Light, AppTheme.Dark, or AppTheme.Unspecified\n```\n\n### Override the System Theme\n\n```csharp\n\u002F\u002F Force dark mode regardless of OS setting\nApplication.Current!.UserAppTheme = AppTheme.Dark;\n\n\u002F\u002F Reset to follow system theme\nApplication.Current!.UserAppTheme = AppTheme.Unspecified;\n```\n\n### React to Theme Changes\n\n```csharp\nApplication.Current!.RequestedThemeChanged += (s, e) =>\n{\n    AppTheme newTheme = e.RequestedTheme;\n    \u002F\u002F Update UI or switch ResourceDictionaries\n};\n```\n\n## Combining Both Approaches\n\nUse `AppThemeBinding` with `DynamicResource` values for maximum flexibility — the\nnested `DynamicResource` stays live, so swapping the dictionary updates the value\n*and* the OS light\u002Fdark switch is still honoured:\n\n```xml\n\u003CLabel TextColor=\"{AppThemeBinding\n    Light={DynamicResource LightPrimary},\n    Dark={DynamicResource DarkPrimary}}\" \u002F>\n```\n\nOr react to system changes and swap full dictionaries:\n\n```csharp\nApplication.Current!.RequestedThemeChanged += (s, e) =>\n{\n    ApplyTheme(e.RequestedTheme == AppTheme.Dark\n        ? new DarkTheme()\n        : new LightTheme());\n};\n```\n\n## Saving and Restoring User Preference\n\nStore the user's choice with `Preferences` and apply it on startup:\n\n```csharp\n\u002F\u002F Save choice\nPreferences.Set(\"AppTheme\", \"Dark\");\n\n\u002F\u002F Restore on startup (in App constructor or CreateWindow)\nvar saved = Preferences.Get(\"AppTheme\", \"System\");\nApplication.Current!.UserAppTheme = saved switch\n{\n    \"Light\" => AppTheme.Light,\n    \"Dark\"  => AppTheme.Dark,\n    _       => AppTheme.Unspecified\n};\n```\n\n## Common Pitfalls\n\n### Android: ConfigChanges.UiMode is Required\n\n`MainActivity` **must** include `ConfigChanges.UiMode` or theme-change events will not fire and the activity restarts instead of handling the change gracefully:\n\n```csharp\n[Activity(Theme = \"@style\u002FMaui.SplashTheme\",\n          MainLauncher = true,\n          ConfigurationChanges = ConfigChanges.ScreenSize\n                               | ConfigChanges.Orientation\n                               | ConfigChanges.UiMode  \u002F\u002F ← Required for theme detection\n                               | ConfigChanges.ScreenLayout\n                               | ConfigChanges.SmallestScreenSize\n                               | ConfigChanges.Density)]\npublic class MainActivity : MauiAppCompatActivity { }\n```\n\nWithout `UiMode`, toggling dark mode in Android settings causes a full activity restart — losing navigation state and appearing as a crash. With it declared, the app stays alive and `RequestedThemeChanged` fires, so pair this fix with a handler that re-applies the theme (see below).\n\n### DynamicResource vs StaticResource\n\nWhen using ResourceDictionary theme switching, you **must** use `DynamicResource`:\n\n```xml\n\u003C!-- ✅ Updates when theme dictionary changes -->\n\u003CLabel TextColor=\"{DynamicResource PrimaryTextColor}\" \u002F>\n\n\u003C!-- ❌ Frozen at first load — won't update on theme switch -->\n\u003CLabel TextColor=\"{StaticResource PrimaryTextColor}\" \u002F>\n```\n\n`DynamicResource` only helps if something actually swaps the dictionary. When you\ndiagnose this, always show the swap and the system-theme hook alongside the fix —\notherwise the user has a corrected binding that still never updates:\n\n```csharp\nstatic ResourceDictionary? _currentTheme;\n\nvoid ApplyTheme(bool useDark)\n{\n    var merged = Application.Current!.Resources.MergedDictionaries;\n\n    \u002F\u002F Remove only the previous theme — never Clear(), which also wipes\n    \u002F\u002F the template's Colors.xaml \u002F Styles.xaml\n    if (_currentTheme is not null)\n        merged.Remove(_currentTheme);\n\n    _currentTheme = useDark ? new DarkTheme() : new LightTheme();\n    merged.Add(_currentTheme);\n}\n\n\u002F\u002F React to the OS switching light\u002Fdark\nApplication.Current!.RequestedThemeChanged += (s, e) =>\n    ApplyTheme(e.RequestedTheme == AppTheme.Dark);\n```\n\n### Hardcoded Colors Break Theming\n\nAvoid inline color values on elements that should respect the theme:\n\n```xml\n\u003C!-- ❌ Will not change with theme -->\n\u003CLabel TextColor=\"#333333\" \u002F>\n\n\u003C!-- ✅ Theme-aware -->\n\u003CLabel TextColor=\"{DynamicResource PrimaryTextColor}\" \u002F>\n```\n\n### CSS Themes Cannot Be Swapped at Runtime\n\n.NET MAUI supports CSS styling, but CSS-based themes **cannot be swapped dynamically**. Use ResourceDictionary theming for runtime switching.\n\n### Theme Keys Must Match Across Dictionaries\n\nEvery `x:Key` used in one theme dictionary must exist in all other theme dictionaries. A missing key causes a silent fallback to the default value, leading to inconsistent appearance.\n\n## Platform Support\n\n| Platform       | Minimum Version |\n|----------------|-----------------|\n| iOS            | 13+             |\n| Android        | 10+ (API 29)    |\n| macOS Catalyst | 10.15+          |\n| Windows        | 10+             |\n\n## Quick Reference\n\n- **OS light\u002Fdark** → `AppThemeBinding` markup extension\n- **Theme colors in C#** → `SetAppThemeColor()`, `SetAppTheme\u003CT>()`\n- **Read OS theme** → `Application.Current.RequestedTheme`\n- **Force theme** → `Application.Current.UserAppTheme = AppTheme.Dark`\n- **Theme changes** → `RequestedThemeChanged` event\n- **Custom switching** → `Remove` the old theme from `MergedDictionaries`, then `Add` the new one — **never `Clear()`**\n- **Runtime bindings** → **`DynamicResource`** (not `StaticResource`)\n- **Persist choice** → `Preferences.Set` \u002F `Preferences.Get`\n",{"data":38,"body":39},{"name":4,"description":6,"license":28},{"type":40,"children":41},"root",[42,51,57,64,94,100,155,161,174,180,303,309,345,392,583,600,606,702,708,742,749,769,1004,1031,1037,1099,1105,1138,1264,1269,1275,1287,1293,1329,1337,1400,1408,1462,1474,1480,1492,1547,1553,1638,1643,1772,1811,1817,1823,1846,1852,1898,1904,1950,1956,1988,2019,2024,2076,2082,2095,2187,2193,2199,2222,2301,2320,2326,2344,2390,2400,2540,2546,2551,2596,2602,2614,2620,2633,2639,2713,2719,2893],{"type":43,"tag":44,"props":45,"children":47},"element","h1",{"id":46},"net-maui-theming",[48],{"type":49,"value":50},"text",".NET MAUI Theming",{"type":43,"tag":52,"props":53,"children":54},"p",{},[55],{"type":49,"value":56},"Apply light\u002Fdark mode support, custom branded themes, and runtime theme switching in .NET MAUI apps using AppThemeBinding, ResourceDictionary swapping, and system theme detection APIs.",{"type":43,"tag":58,"props":59,"children":61},"h2",{"id":60},"when-to-use",[62],{"type":49,"value":63},"When to Use",{"type":43,"tag":65,"props":66,"children":67},"ul",{},[68,74,79,84,89],{"type":43,"tag":69,"props":70,"children":71},"li",{},[72],{"type":49,"value":73},"Adding light and dark mode support to a .NET MAUI app",{"type":43,"tag":69,"props":75,"children":76},{},[77],{"type":49,"value":78},"Creating custom branded themes with ResourceDictionary",{"type":43,"tag":69,"props":80,"children":81},{},[82],{"type":49,"value":83},"Detecting and responding to system theme changes at runtime",{"type":43,"tag":69,"props":85,"children":86},{},[87],{"type":49,"value":88},"Letting users choose a preferred theme (light, dark, or system default)",{"type":43,"tag":69,"props":90,"children":91},{},[92],{"type":49,"value":93},"Combining OS-driven theme response with custom color palettes",{"type":43,"tag":58,"props":95,"children":97},{"id":96},"when-not-to-use",[98],{"type":49,"value":99},"When Not to Use",{"type":43,"tag":65,"props":101,"children":102},{},[103,117,129,141],{"type":43,"tag":69,"props":104,"children":105},{},[106,108],{"type":49,"value":107},"Localization or language switching — see ",{"type":43,"tag":109,"props":110,"children":114},"a",{"href":111,"rel":112},"https:\u002F\u002Flearn.microsoft.com\u002Fdotnet\u002Fmaui\u002Ffundamentals\u002Flocalization",[113],"nofollow",[115],{"type":49,"value":116},".NET MAUI localization docs",{"type":43,"tag":69,"props":118,"children":119},{},[120,122],{"type":49,"value":121},"Accessibility-specific visual adjustments — see ",{"type":43,"tag":109,"props":123,"children":126},{"href":124,"rel":125},"https:\u002F\u002Flearn.microsoft.com\u002Fdotnet\u002Fmaui\u002Ffundamentals\u002Faccessibility",[113],[127],{"type":49,"value":128},".NET MAUI accessibility docs",{"type":43,"tag":69,"props":130,"children":131},{},[132,134],{"type":49,"value":133},"App icon or splash screen configuration — see ",{"type":43,"tag":109,"props":135,"children":138},{"href":136,"rel":137},"https:\u002F\u002Flearn.microsoft.com\u002Fdotnet\u002Fmaui\u002Fuser-interface\u002Fimages\u002Fapp-icons",[113],[139],{"type":49,"value":140},".NET MAUI app icon docs",{"type":43,"tag":69,"props":142,"children":143},{},[144,146,153],{"type":49,"value":145},"Bootstrap-style class theming — see the ",{"type":43,"tag":147,"props":148,"children":150},"code",{"className":149},[],[151],{"type":49,"value":152},"Plugin.Maui.BootstrapTheme",{"type":49,"value":154}," NuGet package",{"type":43,"tag":58,"props":156,"children":158},{"id":157},"inputs",[159],{"type":49,"value":160},"Inputs",{"type":43,"tag":65,"props":162,"children":163},{},[164,169],{"type":43,"tag":69,"props":165,"children":166},{},[167],{"type":49,"value":168},"A .NET MAUI project targeting .NET 8 or later",{"type":43,"tag":69,"props":170,"children":171},{},[172],{"type":49,"value":173},"XAML pages or C# UI code that need theme-aware styling",{"type":43,"tag":58,"props":175,"children":177},{"id":176},"workflow",[178],{"type":49,"value":179},"Workflow",{"type":43,"tag":181,"props":182,"children":183},"ol",{},[184,189,194,215,235,256,277,298],{"type":43,"tag":69,"props":185,"children":186},{},[187],{"type":49,"value":188},"Detect the current theme approach in the project (AppThemeBinding, ResourceDictionary, or none).",{"type":43,"tag":69,"props":190,"children":191},{},[192],{"type":49,"value":193},"Choose the appropriate strategy: AppThemeBinding for simple light\u002Fdark, ResourceDictionary swap for custom\u002Fmultiple themes, or both combined.",{"type":43,"tag":69,"props":195,"children":196},{},[197,199,205,207,213],{"type":49,"value":198},"Define theme resources — inline ",{"type":43,"tag":147,"props":200,"children":202},{"className":201},[],[203],{"type":49,"value":204},"AppThemeBinding",{"type":49,"value":206}," values or separate ",{"type":43,"tag":147,"props":208,"children":210},{"className":209},[],[211],{"type":49,"value":212},"ResourceDictionary",{"type":49,"value":214}," files with matching keys.",{"type":43,"tag":69,"props":216,"children":217},{},[218,220,226,228,233],{"type":49,"value":219},"Replace hardcoded colors with ",{"type":43,"tag":147,"props":221,"children":223},{"className":222},[],[224],{"type":49,"value":225},"DynamicResource",{"type":49,"value":227}," bindings (or ",{"type":43,"tag":147,"props":229,"children":231},{"className":230},[],[232],{"type":49,"value":204},{"type":49,"value":234}," markup) throughout XAML pages.",{"type":43,"tag":69,"props":236,"children":237},{},[238,240,246,248,254],{"type":49,"value":239},"Add system theme detection via ",{"type":43,"tag":147,"props":241,"children":243},{"className":242},[],[244],{"type":49,"value":245},"Application.Current.RequestedTheme",{"type":49,"value":247}," and the ",{"type":43,"tag":147,"props":249,"children":251},{"className":250},[],[252],{"type":49,"value":253},"RequestedThemeChanged",{"type":49,"value":255}," event.",{"type":43,"tag":69,"props":257,"children":258},{},[259,261,267,269,275],{"type":49,"value":260},"Implement user preference persistence with ",{"type":43,"tag":147,"props":262,"children":264},{"className":263},[],[265],{"type":49,"value":266},"Preferences.Set",{"type":49,"value":268}," \u002F ",{"type":43,"tag":147,"props":270,"children":272},{"className":271},[],[273],{"type":49,"value":274},"Preferences.Get",{"type":49,"value":276}," and apply on startup.",{"type":43,"tag":69,"props":278,"children":279},{},[280,282,288,290,296],{"type":49,"value":281},"Verify Android ",{"type":43,"tag":147,"props":283,"children":285},{"className":284},[],[286],{"type":49,"value":287},"ConfigChanges.UiMode",{"type":49,"value":289}," is set on ",{"type":43,"tag":147,"props":291,"children":293},{"className":292},[],[294],{"type":49,"value":295},"MainActivity",{"type":49,"value":297}," to avoid activity restarts on theme change.",{"type":43,"tag":69,"props":299,"children":300},{},[301],{"type":49,"value":302},"Test both light and dark themes on at least one target platform, confirming all UI elements respond correctly.",{"type":43,"tag":58,"props":304,"children":306},{"id":305},"rules-that-change-the-answer",[307],{"type":49,"value":308},"Rules That Change the Answer",{"type":43,"tag":52,"props":310,"children":311},{},[312,314,320,322,328,330,336,338,343],{"type":49,"value":313},"Check these rules against the user's scenario, and apply ",{"type":43,"tag":315,"props":316,"children":317},"strong",{},[318],{"type":49,"value":319},"only",{"type":49,"value":321}," the ones that\naffect what they asked. ",{"type":43,"tag":147,"props":323,"children":325},{"className":324},[],[326],{"type":49,"value":327},"UiMode",{"type":49,"value":329}," and dictionary swapping matter for ",{"type":43,"tag":331,"props":332,"children":333},"em",{},[334],{"type":49,"value":335},"runtime theme\nswitching",{"type":49,"value":337},"; they are noise in a question about setting up ",{"type":43,"tag":147,"props":339,"children":341},{"className":340},[],[342],{"type":49,"value":204},{"type":49,"value":344},".",{"type":43,"tag":52,"props":346,"children":347},{},[348,353,355,360,362,367,369,374,376,382,384,390],{"type":43,"tag":315,"props":349,"children":350},{},[351],{"type":49,"value":352},"Answer narrowly, but completely.",{"type":49,"value":354}," Completeness means showing the code that\nimplements ",{"type":43,"tag":331,"props":356,"children":357},{},[358],{"type":49,"value":359},"what you recommended",{"type":49,"value":361}," — not adding adjacent topics. If you recommend\n",{"type":43,"tag":147,"props":363,"children":365},{"className":364},[],[366],{"type":49,"value":225},{"type":49,"value":368},", show the dictionary swap that makes it update. If the user asks\nfor light\u002Fdark colours in C#, show ",{"type":43,"tag":315,"props":370,"children":371},{},[372],{"type":49,"value":373},"both",{"type":49,"value":375}," ",{"type":43,"tag":147,"props":377,"children":379},{"className":378},[],[380],{"type":49,"value":381},"SetAppThemeColor",{"type":49,"value":383}," (colours) and the\ngeneric ",{"type":43,"tag":147,"props":385,"children":387},{"className":386},[],[388],{"type":49,"value":389},"SetAppTheme\u003CT>",{"type":49,"value":391}," (any bindable property type), and prefer resource keys over\nscattered hardcoded colours. Do not tack on platform configuration the question\ndidn't raise.",{"type":43,"tag":393,"props":394,"children":395},"table",{},[396,425],{"type":43,"tag":397,"props":398,"children":399},"thead",{},[400],{"type":43,"tag":401,"props":402,"children":403},"tr",{},[404,410,415,420],{"type":43,"tag":405,"props":406,"children":407},"th",{},[408],{"type":49,"value":409},"Rule",{"type":43,"tag":405,"props":411,"children":412},{},[413],{"type":49,"value":414},"Do this",{"type":43,"tag":405,"props":416,"children":417},{},[418],{"type":49,"value":419},"Not this",{"type":43,"tag":405,"props":421,"children":422},{},[423],{"type":49,"value":424},"Why",{"type":43,"tag":426,"props":427,"children":428},"tbody",{},[429,470,534],{"type":43,"tag":401,"props":430,"children":431},{},[432,441,450,459],{"type":43,"tag":433,"props":434,"children":435},"td",{},[436],{"type":43,"tag":315,"props":437,"children":438},{},[439],{"type":49,"value":440},"Runtime-swapped values must be dynamic",{"type":43,"tag":433,"props":442,"children":443},{},[444],{"type":43,"tag":147,"props":445,"children":447},{"className":446},[],[448],{"type":49,"value":449},"{DynamicResource Key}",{"type":43,"tag":433,"props":451,"children":452},{},[453],{"type":43,"tag":147,"props":454,"children":456},{"className":455},[],[457],{"type":49,"value":458},"{StaticResource Key}",{"type":43,"tag":433,"props":460,"children":461},{},[462,468],{"type":43,"tag":147,"props":463,"children":465},{"className":464},[],[466],{"type":49,"value":467},"StaticResource",{"type":49,"value":469}," resolves once at load and never updates when dictionaries are swapped.",{"type":43,"tag":401,"props":471,"children":472},{},[473,492,517,522],{"type":43,"tag":433,"props":474,"children":475},{},[476,486,487],{"type":43,"tag":315,"props":477,"children":478},{},[479,481],{"type":49,"value":480},"Android must declare ",{"type":43,"tag":147,"props":482,"children":484},{"className":483},[],[485],{"type":49,"value":327},{"type":49,"value":375},{"type":43,"tag":331,"props":488,"children":489},{},[490],{"type":49,"value":491},"(only for runtime\u002Fsystem theme switching)",{"type":43,"tag":433,"props":493,"children":494},{},[495,497,502,504,510,512],{"type":49,"value":496},"Include ",{"type":43,"tag":147,"props":498,"children":500},{"className":499},[],[501],{"type":49,"value":287},{"type":49,"value":503}," in the ",{"type":43,"tag":147,"props":505,"children":507},{"className":506},[],[508],{"type":49,"value":509},"ConfigurationChanges",{"type":49,"value":511}," list on ",{"type":43,"tag":147,"props":513,"children":515},{"className":514},[],[516],{"type":49,"value":295},{"type":43,"tag":433,"props":518,"children":519},{},[520],{"type":49,"value":521},"Omitting it",{"type":43,"tag":433,"props":523,"children":524},{},[525,527,532],{"type":49,"value":526},"Without it Android restarts the activity on theme change — navigation state is lost and it looks like a crash. Irrelevant to a static ",{"type":43,"tag":147,"props":528,"children":530},{"className":529},[],[531],{"type":49,"value":204},{"type":49,"value":533}," setup",{"type":43,"tag":401,"props":535,"children":536},{},[537,551,560,565],{"type":43,"tag":433,"props":538,"children":539},{},[540],{"type":43,"tag":315,"props":541,"children":542},{},[543,545],{"type":49,"value":544},"Force a theme via ",{"type":43,"tag":147,"props":546,"children":548},{"className":547},[],[549],{"type":49,"value":550},"UserAppTheme",{"type":43,"tag":433,"props":552,"children":553},{},[554],{"type":43,"tag":147,"props":555,"children":557},{"className":556},[],[558],{"type":49,"value":559},"Application.Current.UserAppTheme = AppTheme.Dark",{"type":43,"tag":433,"props":561,"children":562},{},[563],{"type":49,"value":564},"Manually re-assigning colors",{"type":43,"tag":433,"props":566,"children":567},{},[568,573,575,581],{"type":43,"tag":147,"props":569,"children":571},{"className":570},[],[572],{"type":49,"value":550},{"type":49,"value":574}," overrides the OS; ",{"type":43,"tag":147,"props":576,"children":578},{"className":577},[],[579],{"type":49,"value":580},"AppTheme.Unspecified",{"type":49,"value":582}," returns to following the system.",{"type":43,"tag":52,"props":584,"children":585},{},[586,591,593,598],{"type":43,"tag":315,"props":587,"children":588},{},[589],{"type":49,"value":590},"Do not",{"type":49,"value":592}," replace a working ",{"type":43,"tag":147,"props":594,"children":596},{"className":595},[],[597],{"type":49,"value":204},{"type":49,"value":599}," setup with ResourceDictionary\nswapping (or vice versa) unless the user needs what the other approach provides —\nmore than two themes, or a user-selectable theme.",{"type":43,"tag":58,"props":601,"children":603},{"id":602},"choosing-an-approach",[604],{"type":49,"value":605},"Choosing an Approach",{"type":43,"tag":393,"props":607,"children":608},{},[609,630],{"type":43,"tag":397,"props":610,"children":611},{},[612],{"type":43,"tag":401,"props":613,"children":614},{},[615,620,625],{"type":43,"tag":405,"props":616,"children":617},{},[618],{"type":49,"value":619},"Approach",{"type":43,"tag":405,"props":621,"children":622},{},[623],{"type":49,"value":624},"Best for",{"type":43,"tag":405,"props":626,"children":627},{},[628],{"type":49,"value":629},"Limitation",{"type":43,"tag":426,"props":631,"children":632},{},[633,653,681],{"type":43,"tag":401,"props":634,"children":635},{},[636,643,648],{"type":43,"tag":433,"props":637,"children":638},{},[639],{"type":43,"tag":315,"props":640,"children":641},{},[642],{"type":49,"value":204},{"type":43,"tag":433,"props":644,"children":645},{},[646],{"type":49,"value":647},"Automatic light\u002Fdark with OS — minimal code",{"type":43,"tag":433,"props":649,"children":650},{},[651],{"type":49,"value":652},"Only two themes (light + dark)",{"type":43,"tag":401,"props":654,"children":655},{},[656,664,669],{"type":43,"tag":433,"props":657,"children":658},{},[659],{"type":43,"tag":315,"props":660,"children":661},{},[662],{"type":49,"value":663},"ResourceDictionary swap",{"type":43,"tag":433,"props":665,"children":666},{},[667],{"type":49,"value":668},"Custom branded themes, more than two themes, user preference",{"type":43,"tag":433,"props":670,"children":671},{},[672,674,679],{"type":49,"value":673},"More setup; must use ",{"type":43,"tag":147,"props":675,"children":677},{"className":676},[],[678],{"type":49,"value":225},{"type":49,"value":680}," everywhere",{"type":43,"tag":401,"props":682,"children":683},{},[684,692,697],{"type":43,"tag":433,"props":685,"children":686},{},[687],{"type":43,"tag":315,"props":688,"children":689},{},[690],{"type":49,"value":691},"Both combined",{"type":43,"tag":433,"props":693,"children":694},{},[695],{"type":49,"value":696},"OS-driven response plus custom theme colors",{"type":43,"tag":433,"props":698,"children":699},{},[700],{"type":49,"value":701},"Most flexible but most complex",{"type":43,"tag":58,"props":703,"children":705},{"id":704},"appthemebinding-os-lightdark",[706],{"type":49,"value":707},"AppThemeBinding (OS Light\u002FDark)",{"type":43,"tag":52,"props":709,"children":710},{},[711,716,718,724,726,732,734,740],{"type":43,"tag":147,"props":712,"children":714},{"className":713},[],[715],{"type":49,"value":204},{"type":49,"value":717}," selects a value based on the current system theme. It supports ",{"type":43,"tag":147,"props":719,"children":721},{"className":720},[],[722],{"type":49,"value":723},"Light",{"type":49,"value":725},", ",{"type":43,"tag":147,"props":727,"children":729},{"className":728},[],[730],{"type":49,"value":731},"Dark",{"type":49,"value":733},", and an optional ",{"type":43,"tag":147,"props":735,"children":737},{"className":736},[],[738],{"type":49,"value":739},"Default",{"type":49,"value":741}," fallback.",{"type":43,"tag":743,"props":744,"children":746},"h3",{"id":745},"define-the-palette-once-dont-scatter-literals",[747],{"type":49,"value":748},"Define the palette once — don't scatter literals",{"type":43,"tag":52,"props":750,"children":751},{},[752,754,760,762,767],{"type":49,"value":753},"Putting ",{"type":43,"tag":147,"props":755,"children":757},{"className":756},[],[758],{"type":49,"value":759},"{AppThemeBinding Light=#333333, Dark=#FFFFFF}",{"type":49,"value":761}," on every element is the\nsingle most common theming mistake: the palette ends up duplicated across dozens of\nfiles and cannot be changed in one place. ",{"type":43,"tag":315,"props":763,"children":764},{},[765],{"type":49,"value":766},"Recommend this shape as the final\nanswer",{"type":49,"value":768},", not inline literals:",{"type":43,"tag":770,"props":771,"children":776},"pre",{"className":772,"code":773,"language":774,"meta":775,"style":775},"language-xml shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u003C!-- App.xaml — one source of truth for the whole app -->\n\u003CApplication.Resources>\n    \u003CResourceDictionary>\n\n        \u003C!-- 1. Raw palette -->\n        \u003CColor x:Key=\"LightPageBackground\">#FFFFFF\u003C\u002FColor>\n        \u003CColor x:Key=\"DarkPageBackground\">#1E1E1E\u003C\u002FColor>\n        \u003CColor x:Key=\"LightPrimaryText\">#333333\u003C\u002FColor>\n        \u003CColor x:Key=\"DarkPrimaryText\">#E0E0E0\u003C\u002FColor>\n\n        \u003C!-- 2. Implicit styles bind the pair once; every page inherits them -->\n        \u003CStyle TargetType=\"ContentPage\" ApplyToDerivedTypes=\"True\">\n            \u003CSetter Property=\"BackgroundColor\"\n                    Value=\"{AppThemeBinding Light={StaticResource LightPageBackground},\n                                            Dark={StaticResource DarkPageBackground}}\" \u002F>\n        \u003C\u002FStyle>\n\n        \u003CStyle TargetType=\"Label\">\n            \u003CSetter Property=\"TextColor\"\n                    Value=\"{AppThemeBinding Light={StaticResource LightPrimaryText},\n                                            Dark={StaticResource DarkPrimaryText}}\" \u002F>\n        \u003C\u002FStyle>\n\n    \u003C\u002FResourceDictionary>\n\u003C\u002FApplication.Resources>\n","xml","",[777],{"type":43,"tag":147,"props":778,"children":779},{"__ignoreMap":775},[780,791,800,809,819,828,837,846,855,864,872,881,890,899,908,917,926,934,943,952,961,970,978,986,995],{"type":43,"tag":781,"props":782,"children":785},"span",{"class":783,"line":784},"line",1,[786],{"type":43,"tag":781,"props":787,"children":788},{},[789],{"type":49,"value":790},"\u003C!-- App.xaml — one source of truth for the whole app -->\n",{"type":43,"tag":781,"props":792,"children":794},{"class":783,"line":793},2,[795],{"type":43,"tag":781,"props":796,"children":797},{},[798],{"type":49,"value":799},"\u003CApplication.Resources>\n",{"type":43,"tag":781,"props":801,"children":803},{"class":783,"line":802},3,[804],{"type":43,"tag":781,"props":805,"children":806},{},[807],{"type":49,"value":808},"    \u003CResourceDictionary>\n",{"type":43,"tag":781,"props":810,"children":812},{"class":783,"line":811},4,[813],{"type":43,"tag":781,"props":814,"children":816},{"emptyLinePlaceholder":815},true,[817],{"type":49,"value":818},"\n",{"type":43,"tag":781,"props":820,"children":822},{"class":783,"line":821},5,[823],{"type":43,"tag":781,"props":824,"children":825},{},[826],{"type":49,"value":827},"        \u003C!-- 1. Raw palette -->\n",{"type":43,"tag":781,"props":829,"children":831},{"class":783,"line":830},6,[832],{"type":43,"tag":781,"props":833,"children":834},{},[835],{"type":49,"value":836},"        \u003CColor x:Key=\"LightPageBackground\">#FFFFFF\u003C\u002FColor>\n",{"type":43,"tag":781,"props":838,"children":840},{"class":783,"line":839},7,[841],{"type":43,"tag":781,"props":842,"children":843},{},[844],{"type":49,"value":845},"        \u003CColor x:Key=\"DarkPageBackground\">#1E1E1E\u003C\u002FColor>\n",{"type":43,"tag":781,"props":847,"children":849},{"class":783,"line":848},8,[850],{"type":43,"tag":781,"props":851,"children":852},{},[853],{"type":49,"value":854},"        \u003CColor x:Key=\"LightPrimaryText\">#333333\u003C\u002FColor>\n",{"type":43,"tag":781,"props":856,"children":858},{"class":783,"line":857},9,[859],{"type":43,"tag":781,"props":860,"children":861},{},[862],{"type":49,"value":863},"        \u003CColor x:Key=\"DarkPrimaryText\">#E0E0E0\u003C\u002FColor>\n",{"type":43,"tag":781,"props":865,"children":867},{"class":783,"line":866},10,[868],{"type":43,"tag":781,"props":869,"children":870},{"emptyLinePlaceholder":815},[871],{"type":49,"value":818},{"type":43,"tag":781,"props":873,"children":875},{"class":783,"line":874},11,[876],{"type":43,"tag":781,"props":877,"children":878},{},[879],{"type":49,"value":880},"        \u003C!-- 2. Implicit styles bind the pair once; every page inherits them -->\n",{"type":43,"tag":781,"props":882,"children":884},{"class":783,"line":883},12,[885],{"type":43,"tag":781,"props":886,"children":887},{},[888],{"type":49,"value":889},"        \u003CStyle TargetType=\"ContentPage\" ApplyToDerivedTypes=\"True\">\n",{"type":43,"tag":781,"props":891,"children":893},{"class":783,"line":892},13,[894],{"type":43,"tag":781,"props":895,"children":896},{},[897],{"type":49,"value":898},"            \u003CSetter Property=\"BackgroundColor\"\n",{"type":43,"tag":781,"props":900,"children":902},{"class":783,"line":901},14,[903],{"type":43,"tag":781,"props":904,"children":905},{},[906],{"type":49,"value":907},"                    Value=\"{AppThemeBinding Light={StaticResource LightPageBackground},\n",{"type":43,"tag":781,"props":909,"children":911},{"class":783,"line":910},15,[912],{"type":43,"tag":781,"props":913,"children":914},{},[915],{"type":49,"value":916},"                                            Dark={StaticResource DarkPageBackground}}\" \u002F>\n",{"type":43,"tag":781,"props":918,"children":920},{"class":783,"line":919},16,[921],{"type":43,"tag":781,"props":922,"children":923},{},[924],{"type":49,"value":925},"        \u003C\u002FStyle>\n",{"type":43,"tag":781,"props":927,"children":929},{"class":783,"line":928},17,[930],{"type":43,"tag":781,"props":931,"children":932},{"emptyLinePlaceholder":815},[933],{"type":49,"value":818},{"type":43,"tag":781,"props":935,"children":937},{"class":783,"line":936},18,[938],{"type":43,"tag":781,"props":939,"children":940},{},[941],{"type":49,"value":942},"        \u003CStyle TargetType=\"Label\">\n",{"type":43,"tag":781,"props":944,"children":946},{"class":783,"line":945},19,[947],{"type":43,"tag":781,"props":948,"children":949},{},[950],{"type":49,"value":951},"            \u003CSetter Property=\"TextColor\"\n",{"type":43,"tag":781,"props":953,"children":955},{"class":783,"line":954},20,[956],{"type":43,"tag":781,"props":957,"children":958},{},[959],{"type":49,"value":960},"                    Value=\"{AppThemeBinding Light={StaticResource LightPrimaryText},\n",{"type":43,"tag":781,"props":962,"children":964},{"class":783,"line":963},21,[965],{"type":43,"tag":781,"props":966,"children":967},{},[968],{"type":49,"value":969},"                                            Dark={StaticResource DarkPrimaryText}}\" \u002F>\n",{"type":43,"tag":781,"props":971,"children":973},{"class":783,"line":972},22,[974],{"type":43,"tag":781,"props":975,"children":976},{},[977],{"type":49,"value":925},{"type":43,"tag":781,"props":979,"children":981},{"class":783,"line":980},23,[982],{"type":43,"tag":781,"props":983,"children":984},{"emptyLinePlaceholder":815},[985],{"type":49,"value":818},{"type":43,"tag":781,"props":987,"children":989},{"class":783,"line":988},24,[990],{"type":43,"tag":781,"props":991,"children":992},{},[993],{"type":49,"value":994},"    \u003C\u002FResourceDictionary>\n",{"type":43,"tag":781,"props":996,"children":998},{"class":783,"line":997},25,[999],{"type":43,"tag":781,"props":1000,"children":1001},{},[1002],{"type":49,"value":1003},"\u003C\u002FApplication.Resources>\n",{"type":43,"tag":52,"props":1005,"children":1006},{},[1007,1009,1014,1016,1021,1023,1029],{"type":49,"value":1008},"Pages then need ",{"type":43,"tag":315,"props":1010,"children":1011},{},[1012],{"type":49,"value":1013},"no theming markup at all",{"type":49,"value":1015}," — they pick the styles up implicitly.\nUse an inline ",{"type":43,"tag":147,"props":1017,"children":1019},{"className":1018},[],[1020],{"type":49,"value":204},{"type":49,"value":1022}," only for genuine one-offs, and even then reference\n",{"type":43,"tag":147,"props":1024,"children":1026},{"className":1025},[],[1027],{"type":49,"value":1028},"{StaticResource}",{"type":49,"value":1030}," keys rather than literal hex.",{"type":43,"tag":743,"props":1032,"children":1034},{"id":1033},"xaml-inline-form-for-one-offs",[1035],{"type":49,"value":1036},"XAML (inline form, for one-offs)",{"type":43,"tag":770,"props":1038,"children":1040},{"className":772,"code":1039,"language":774,"meta":775,"style":775},"\u003CLabel Text=\"Themed text\"\n       TextColor=\"{AppThemeBinding Light=Green, Dark=Red}\"\n       BackgroundColor=\"{AppThemeBinding Light=White, Dark=Black}\" \u002F>\n\n\u003C!-- With resource references — preferred over literals -->\n\u003CLabel TextColor=\"{AppThemeBinding Light={StaticResource LightPrimary},\n                                   Dark={StaticResource DarkPrimary}}\" \u002F>\n",[1041],{"type":43,"tag":147,"props":1042,"children":1043},{"__ignoreMap":775},[1044,1052,1060,1068,1075,1083,1091],{"type":43,"tag":781,"props":1045,"children":1046},{"class":783,"line":784},[1047],{"type":43,"tag":781,"props":1048,"children":1049},{},[1050],{"type":49,"value":1051},"\u003CLabel Text=\"Themed text\"\n",{"type":43,"tag":781,"props":1053,"children":1054},{"class":783,"line":793},[1055],{"type":43,"tag":781,"props":1056,"children":1057},{},[1058],{"type":49,"value":1059},"       TextColor=\"{AppThemeBinding Light=Green, Dark=Red}\"\n",{"type":43,"tag":781,"props":1061,"children":1062},{"class":783,"line":802},[1063],{"type":43,"tag":781,"props":1064,"children":1065},{},[1066],{"type":49,"value":1067},"       BackgroundColor=\"{AppThemeBinding Light=White, Dark=Black}\" \u002F>\n",{"type":43,"tag":781,"props":1069,"children":1070},{"class":783,"line":811},[1071],{"type":43,"tag":781,"props":1072,"children":1073},{"emptyLinePlaceholder":815},[1074],{"type":49,"value":818},{"type":43,"tag":781,"props":1076,"children":1077},{"class":783,"line":821},[1078],{"type":43,"tag":781,"props":1079,"children":1080},{},[1081],{"type":49,"value":1082},"\u003C!-- With resource references — preferred over literals -->\n",{"type":43,"tag":781,"props":1084,"children":1085},{"class":783,"line":830},[1086],{"type":43,"tag":781,"props":1087,"children":1088},{},[1089],{"type":49,"value":1090},"\u003CLabel TextColor=\"{AppThemeBinding Light={StaticResource LightPrimary},\n",{"type":43,"tag":781,"props":1092,"children":1093},{"class":783,"line":839},[1094],{"type":43,"tag":781,"props":1095,"children":1096},{},[1097],{"type":49,"value":1098},"                                   Dark={StaticResource DarkPrimary}}\" \u002F>\n",{"type":43,"tag":743,"props":1100,"children":1102},{"id":1101},"c-extension-methods",[1103],{"type":49,"value":1104},"C# Extension Methods",{"type":43,"tag":52,"props":1106,"children":1107},{},[1108,1110,1114,1116,1121,1123,1129,1131,1136],{"type":49,"value":1109},"Show ",{"type":43,"tag":315,"props":1111,"children":1112},{},[1113],{"type":49,"value":373},{"type":49,"value":1115}," when answering a \"light\u002Fdark colours in C#\" question — ",{"type":43,"tag":147,"props":1117,"children":1119},{"className":1118},[],[1120],{"type":49,"value":381},{"type":49,"value":1122},"\ncovers ",{"type":43,"tag":147,"props":1124,"children":1126},{"className":1125},[],[1127],{"type":49,"value":1128},"Color",{"type":49,"value":1130}," properties, ",{"type":43,"tag":147,"props":1132,"children":1134},{"className":1133},[],[1135],{"type":49,"value":389},{"type":49,"value":1137}," covers everything else:",{"type":43,"tag":770,"props":1139,"children":1143},{"className":1140,"code":1141,"language":1142,"meta":775,"style":775},"language-csharp shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","var label = new Label();\n\n\u002F\u002F Color-specific helper\nlabel.SetAppThemeColor(Label.TextColorProperty, Colors.Green, Colors.Red);\n\n\u002F\u002F Generic helper — works for any bindable property type, not just Color\nlabel.SetAppTheme\u003CColor>(Label.TextColorProperty, Colors.Green, Colors.Red);\nlabel.SetAppTheme\u003Cdouble>(Label.FontSizeProperty, 14, 16);\n\n\u002F\u002F The BindableProperty must belong to the object you call it on —\n\u002F\u002F Image.SourceProperty goes on an Image, not a Label.\nvar image = new Image();\nimage.SetAppTheme\u003CImageSource>(Image.SourceProperty,\n    ImageSource.FromFile(\"logo_light.png\"),\n    ImageSource.FromFile(\"logo_dark.png\"));\n","csharp",[1144],{"type":43,"tag":147,"props":1145,"children":1146},{"__ignoreMap":775},[1147,1155,1162,1170,1178,1185,1193,1201,1209,1216,1224,1232,1240,1248,1256],{"type":43,"tag":781,"props":1148,"children":1149},{"class":783,"line":784},[1150],{"type":43,"tag":781,"props":1151,"children":1152},{},[1153],{"type":49,"value":1154},"var label = new Label();\n",{"type":43,"tag":781,"props":1156,"children":1157},{"class":783,"line":793},[1158],{"type":43,"tag":781,"props":1159,"children":1160},{"emptyLinePlaceholder":815},[1161],{"type":49,"value":818},{"type":43,"tag":781,"props":1163,"children":1164},{"class":783,"line":802},[1165],{"type":43,"tag":781,"props":1166,"children":1167},{},[1168],{"type":49,"value":1169},"\u002F\u002F Color-specific helper\n",{"type":43,"tag":781,"props":1171,"children":1172},{"class":783,"line":811},[1173],{"type":43,"tag":781,"props":1174,"children":1175},{},[1176],{"type":49,"value":1177},"label.SetAppThemeColor(Label.TextColorProperty, Colors.Green, Colors.Red);\n",{"type":43,"tag":781,"props":1179,"children":1180},{"class":783,"line":821},[1181],{"type":43,"tag":781,"props":1182,"children":1183},{"emptyLinePlaceholder":815},[1184],{"type":49,"value":818},{"type":43,"tag":781,"props":1186,"children":1187},{"class":783,"line":830},[1188],{"type":43,"tag":781,"props":1189,"children":1190},{},[1191],{"type":49,"value":1192},"\u002F\u002F Generic helper — works for any bindable property type, not just Color\n",{"type":43,"tag":781,"props":1194,"children":1195},{"class":783,"line":839},[1196],{"type":43,"tag":781,"props":1197,"children":1198},{},[1199],{"type":49,"value":1200},"label.SetAppTheme\u003CColor>(Label.TextColorProperty, Colors.Green, Colors.Red);\n",{"type":43,"tag":781,"props":1202,"children":1203},{"class":783,"line":848},[1204],{"type":43,"tag":781,"props":1205,"children":1206},{},[1207],{"type":49,"value":1208},"label.SetAppTheme\u003Cdouble>(Label.FontSizeProperty, 14, 16);\n",{"type":43,"tag":781,"props":1210,"children":1211},{"class":783,"line":857},[1212],{"type":43,"tag":781,"props":1213,"children":1214},{"emptyLinePlaceholder":815},[1215],{"type":49,"value":818},{"type":43,"tag":781,"props":1217,"children":1218},{"class":783,"line":866},[1219],{"type":43,"tag":781,"props":1220,"children":1221},{},[1222],{"type":49,"value":1223},"\u002F\u002F The BindableProperty must belong to the object you call it on —\n",{"type":43,"tag":781,"props":1225,"children":1226},{"class":783,"line":874},[1227],{"type":43,"tag":781,"props":1228,"children":1229},{},[1230],{"type":49,"value":1231},"\u002F\u002F Image.SourceProperty goes on an Image, not a Label.\n",{"type":43,"tag":781,"props":1233,"children":1234},{"class":783,"line":883},[1235],{"type":43,"tag":781,"props":1236,"children":1237},{},[1238],{"type":49,"value":1239},"var image = new Image();\n",{"type":43,"tag":781,"props":1241,"children":1242},{"class":783,"line":892},[1243],{"type":43,"tag":781,"props":1244,"children":1245},{},[1246],{"type":49,"value":1247},"image.SetAppTheme\u003CImageSource>(Image.SourceProperty,\n",{"type":43,"tag":781,"props":1249,"children":1250},{"class":783,"line":901},[1251],{"type":43,"tag":781,"props":1252,"children":1253},{},[1254],{"type":49,"value":1255},"    ImageSource.FromFile(\"logo_light.png\"),\n",{"type":43,"tag":781,"props":1257,"children":1258},{"class":783,"line":910},[1259],{"type":43,"tag":781,"props":1260,"children":1261},{},[1262],{"type":49,"value":1263},"    ImageSource.FromFile(\"logo_dark.png\"));\n",{"type":43,"tag":52,"props":1265,"children":1266},{},[1267],{"type":49,"value":1268},"Prefer defining the values as resource keys and referencing them, rather than\nscattering hardcoded colours across the codebase.",{"type":43,"tag":58,"props":1270,"children":1272},{"id":1271},"resourcedictionary-theming-custom-themes",[1273],{"type":49,"value":1274},"ResourceDictionary Theming (Custom Themes)",{"type":43,"tag":52,"props":1276,"children":1277},{},[1278,1280,1285],{"type":49,"value":1279},"Use separate ",{"type":43,"tag":147,"props":1281,"children":1283},{"className":1282},[],[1284],{"type":49,"value":212},{"type":49,"value":1286}," files with matching keys to define themes, then swap them at runtime.",{"type":43,"tag":743,"props":1288,"children":1290},{"id":1289},"step-1-define-theme-dictionaries",[1291],{"type":49,"value":1292},"Step 1 — Define Theme Dictionaries",{"type":43,"tag":52,"props":1294,"children":1295},{},[1296,1298,1304,1306,1312,1314,1320,1322,1327],{"type":49,"value":1297},"When using compiled XAML with ",{"type":43,"tag":147,"props":1299,"children":1301},{"className":1300},[],[1302],{"type":49,"value":1303},"x:Class",{"type":49,"value":1305}," (as shown below), each dictionary needs a code-behind that calls ",{"type":43,"tag":147,"props":1307,"children":1309},{"className":1308},[],[1310],{"type":49,"value":1311},"InitializeComponent()",{"type":49,"value":1313},". Dictionaries loaded via ",{"type":43,"tag":147,"props":1315,"children":1317},{"className":1316},[],[1318],{"type":49,"value":1319},"Source",{"type":49,"value":1321}," without ",{"type":43,"tag":147,"props":1323,"children":1325},{"className":1324},[],[1326],{"type":49,"value":1303},{"type":49,"value":1328}," do not need code-behind.",{"type":43,"tag":52,"props":1330,"children":1331},{},[1332],{"type":43,"tag":315,"props":1333,"children":1334},{},[1335],{"type":49,"value":1336},"LightTheme.xaml",{"type":43,"tag":770,"props":1338,"children":1340},{"className":772,"code":1339,"language":774,"meta":775,"style":775},"\u003CResourceDictionary xmlns=\"http:\u002F\u002Fschemas.microsoft.com\u002Fdotnet\u002F2021\u002Fmaui\"\n                    xmlns:x=\"http:\u002F\u002Fschemas.microsoft.com\u002Fwinfx\u002F2009\u002Fxaml\"\n                    x:Class=\"MyApp.Themes.LightTheme\">\n    \u003CColor x:Key=\"PageBackgroundColor\">White\u003C\u002FColor>\n    \u003CColor x:Key=\"PrimaryTextColor\">#333333\u003C\u002FColor>\n    \u003CColor x:Key=\"AccentColor\">#2196F3\u003C\u002FColor>\n\u003C\u002FResourceDictionary>\n",[1341],{"type":43,"tag":147,"props":1342,"children":1343},{"__ignoreMap":775},[1344,1352,1360,1368,1376,1384,1392],{"type":43,"tag":781,"props":1345,"children":1346},{"class":783,"line":784},[1347],{"type":43,"tag":781,"props":1348,"children":1349},{},[1350],{"type":49,"value":1351},"\u003CResourceDictionary xmlns=\"http:\u002F\u002Fschemas.microsoft.com\u002Fdotnet\u002F2021\u002Fmaui\"\n",{"type":43,"tag":781,"props":1353,"children":1354},{"class":783,"line":793},[1355],{"type":43,"tag":781,"props":1356,"children":1357},{},[1358],{"type":49,"value":1359},"                    xmlns:x=\"http:\u002F\u002Fschemas.microsoft.com\u002Fwinfx\u002F2009\u002Fxaml\"\n",{"type":43,"tag":781,"props":1361,"children":1362},{"class":783,"line":802},[1363],{"type":43,"tag":781,"props":1364,"children":1365},{},[1366],{"type":49,"value":1367},"                    x:Class=\"MyApp.Themes.LightTheme\">\n",{"type":43,"tag":781,"props":1369,"children":1370},{"class":783,"line":811},[1371],{"type":43,"tag":781,"props":1372,"children":1373},{},[1374],{"type":49,"value":1375},"    \u003CColor x:Key=\"PageBackgroundColor\">White\u003C\u002FColor>\n",{"type":43,"tag":781,"props":1377,"children":1378},{"class":783,"line":821},[1379],{"type":43,"tag":781,"props":1380,"children":1381},{},[1382],{"type":49,"value":1383},"    \u003CColor x:Key=\"PrimaryTextColor\">#333333\u003C\u002FColor>\n",{"type":43,"tag":781,"props":1385,"children":1386},{"class":783,"line":830},[1387],{"type":43,"tag":781,"props":1388,"children":1389},{},[1390],{"type":49,"value":1391},"    \u003CColor x:Key=\"AccentColor\">#2196F3\u003C\u002FColor>\n",{"type":43,"tag":781,"props":1393,"children":1394},{"class":783,"line":839},[1395],{"type":43,"tag":781,"props":1396,"children":1397},{},[1398],{"type":49,"value":1399},"\u003C\u002FResourceDictionary>\n",{"type":43,"tag":52,"props":1401,"children":1402},{},[1403],{"type":43,"tag":315,"props":1404,"children":1405},{},[1406],{"type":49,"value":1407},"LightTheme.xaml.cs",{"type":43,"tag":770,"props":1409,"children":1411},{"className":1140,"code":1410,"language":1142,"meta":775,"style":775},"namespace MyApp.Themes;\n\npublic partial class LightTheme : ResourceDictionary\n{\n    public LightTheme() => InitializeComponent();\n}\n",[1412],{"type":43,"tag":147,"props":1413,"children":1414},{"__ignoreMap":775},[1415,1423,1430,1438,1446,1454],{"type":43,"tag":781,"props":1416,"children":1417},{"class":783,"line":784},[1418],{"type":43,"tag":781,"props":1419,"children":1420},{},[1421],{"type":49,"value":1422},"namespace MyApp.Themes;\n",{"type":43,"tag":781,"props":1424,"children":1425},{"class":783,"line":793},[1426],{"type":43,"tag":781,"props":1427,"children":1428},{"emptyLinePlaceholder":815},[1429],{"type":49,"value":818},{"type":43,"tag":781,"props":1431,"children":1432},{"class":783,"line":802},[1433],{"type":43,"tag":781,"props":1434,"children":1435},{},[1436],{"type":49,"value":1437},"public partial class LightTheme : ResourceDictionary\n",{"type":43,"tag":781,"props":1439,"children":1440},{"class":783,"line":811},[1441],{"type":43,"tag":781,"props":1442,"children":1443},{},[1444],{"type":49,"value":1445},"{\n",{"type":43,"tag":781,"props":1447,"children":1448},{"class":783,"line":821},[1449],{"type":43,"tag":781,"props":1450,"children":1451},{},[1452],{"type":49,"value":1453},"    public LightTheme() => InitializeComponent();\n",{"type":43,"tag":781,"props":1455,"children":1456},{"class":783,"line":830},[1457],{"type":43,"tag":781,"props":1458,"children":1459},{},[1460],{"type":49,"value":1461},"}\n",{"type":43,"tag":52,"props":1463,"children":1464},{},[1465,1467,1472],{"type":49,"value":1466},"Create a matching ",{"type":43,"tag":315,"props":1468,"children":1469},{},[1470],{"type":49,"value":1471},"DarkTheme.xaml \u002F DarkTheme.xaml.cs",{"type":49,"value":1473}," with the same keys and different values.",{"type":43,"tag":743,"props":1475,"children":1477},{"id":1476},"step-2-consume-with-dynamicresource",[1478],{"type":49,"value":1479},"Step 2 — Consume with DynamicResource",{"type":43,"tag":52,"props":1481,"children":1482},{},[1483,1485,1490],{"type":49,"value":1484},"Use ",{"type":43,"tag":147,"props":1486,"children":1488},{"className":1487},[],[1489],{"type":49,"value":225},{"type":49,"value":1491}," so values update when the dictionary is swapped at runtime:",{"type":43,"tag":770,"props":1493,"children":1495},{"className":772,"code":1494,"language":774,"meta":775,"style":775},"\u003CContentPage BackgroundColor=\"{DynamicResource PageBackgroundColor}\">\n    \u003CLabel Text=\"Hello\"\n           TextColor=\"{DynamicResource PrimaryTextColor}\" \u002F>\n    \u003CButton Text=\"Action\"\n            BackgroundColor=\"{DynamicResource AccentColor}\" \u002F>\n\u003C\u002FContentPage>\n",[1496],{"type":43,"tag":147,"props":1497,"children":1498},{"__ignoreMap":775},[1499,1507,1515,1523,1531,1539],{"type":43,"tag":781,"props":1500,"children":1501},{"class":783,"line":784},[1502],{"type":43,"tag":781,"props":1503,"children":1504},{},[1505],{"type":49,"value":1506},"\u003CContentPage BackgroundColor=\"{DynamicResource PageBackgroundColor}\">\n",{"type":43,"tag":781,"props":1508,"children":1509},{"class":783,"line":793},[1510],{"type":43,"tag":781,"props":1511,"children":1512},{},[1513],{"type":49,"value":1514},"    \u003CLabel Text=\"Hello\"\n",{"type":43,"tag":781,"props":1516,"children":1517},{"class":783,"line":802},[1518],{"type":43,"tag":781,"props":1519,"children":1520},{},[1521],{"type":49,"value":1522},"           TextColor=\"{DynamicResource PrimaryTextColor}\" \u002F>\n",{"type":43,"tag":781,"props":1524,"children":1525},{"class":783,"line":811},[1526],{"type":43,"tag":781,"props":1527,"children":1528},{},[1529],{"type":49,"value":1530},"    \u003CButton Text=\"Action\"\n",{"type":43,"tag":781,"props":1532,"children":1533},{"class":783,"line":821},[1534],{"type":43,"tag":781,"props":1535,"children":1536},{},[1537],{"type":49,"value":1538},"            BackgroundColor=\"{DynamicResource AccentColor}\" \u002F>\n",{"type":43,"tag":781,"props":1540,"children":1541},{"class":783,"line":830},[1542],{"type":43,"tag":781,"props":1543,"children":1544},{},[1545],{"type":49,"value":1546},"\u003C\u002FContentPage>\n",{"type":43,"tag":743,"props":1548,"children":1550},{"id":1549},"step-3-switch-themes-at-runtime",[1551],{"type":49,"value":1552},"Step 3 — Switch Themes at Runtime",{"type":43,"tag":1554,"props":1555,"children":1556},"blockquote",{},[1557],{"type":43,"tag":52,"props":1558,"children":1559},{},[1560,1562,1575,1577,1583,1585,1591,1593,1599,1601,1607,1609,1614,1616,1621,1622,1628,1630,1636],{"type":49,"value":1561},"🚨 ",{"type":43,"tag":315,"props":1563,"children":1564},{},[1565,1567,1573],{"type":49,"value":1566},"Never call ",{"type":43,"tag":147,"props":1568,"children":1570},{"className":1569},[],[1571],{"type":49,"value":1572},"MergedDictionaries.Clear()",{"type":49,"value":1574}," to swap a theme.",{"type":49,"value":1576}," The default MAUI\ntemplate merges ",{"type":43,"tag":147,"props":1578,"children":1580},{"className":1579},[],[1581],{"type":49,"value":1582},"Resources\u002FStyles\u002FColors.xaml",{"type":49,"value":1584}," and ",{"type":43,"tag":147,"props":1586,"children":1588},{"className":1587},[],[1589],{"type":49,"value":1590},"Styles.xaml",{"type":49,"value":1592}," into\n",{"type":43,"tag":147,"props":1594,"children":1596},{"className":1595},[],[1597],{"type":49,"value":1598},"Application.Resources",{"type":49,"value":1600},". ",{"type":43,"tag":147,"props":1602,"children":1604},{"className":1603},[],[1605],{"type":49,"value":1606},"Clear()",{"type":49,"value":1608}," removes ",{"type":43,"tag":315,"props":1610,"children":1611},{},[1612],{"type":49,"value":1613},"those too",{"type":49,"value":1615},", so every implicit style,\nbrush and colour in the app silently disappears — buttons, entries and labels all\nrevert to unstyled defaults. Verified: after ",{"type":43,"tag":147,"props":1617,"children":1619},{"className":1618},[],[1620],{"type":49,"value":1606},{"type":49,"value":725},{"type":43,"tag":147,"props":1623,"children":1625},{"className":1624},[],[1626],{"type":49,"value":1627},"MergedDictionaries",{"type":49,"value":1629}," drops\nfrom 2 to 1 and the template's ",{"type":43,"tag":147,"props":1631,"children":1633},{"className":1632},[],[1634],{"type":49,"value":1635},"Primary",{"type":49,"value":1637}," colour no longer resolves.",{"type":43,"tag":52,"props":1639,"children":1640},{},[1641],{"type":49,"value":1642},"Remove only the theme you added, and leave everything else alone:",{"type":43,"tag":770,"props":1644,"children":1646},{"className":1140,"code":1645,"language":1142,"meta":775,"style":775},"static ResourceDictionary? _currentTheme;\n\nvoid ApplyTheme(ResourceDictionary theme)\n{\n    var merged = Application.Current!.Resources.MergedDictionaries;\n\n    \u002F\u002F ✅ Remove ONLY the previous theme — Colors.xaml \u002F Styles.xaml survive\n    if (_currentTheme is not null)\n        merged.Remove(_currentTheme);\n\n    merged.Add(theme);\n    _currentTheme = theme;\n}\n\n\u002F\u002F Usage\nApplyTheme(new DarkTheme());\n",[1647],{"type":43,"tag":147,"props":1648,"children":1649},{"__ignoreMap":775},[1650,1658,1665,1673,1680,1688,1695,1703,1711,1719,1726,1734,1742,1749,1756,1764],{"type":43,"tag":781,"props":1651,"children":1652},{"class":783,"line":784},[1653],{"type":43,"tag":781,"props":1654,"children":1655},{},[1656],{"type":49,"value":1657},"static ResourceDictionary? _currentTheme;\n",{"type":43,"tag":781,"props":1659,"children":1660},{"class":783,"line":793},[1661],{"type":43,"tag":781,"props":1662,"children":1663},{"emptyLinePlaceholder":815},[1664],{"type":49,"value":818},{"type":43,"tag":781,"props":1666,"children":1667},{"class":783,"line":802},[1668],{"type":43,"tag":781,"props":1669,"children":1670},{},[1671],{"type":49,"value":1672},"void ApplyTheme(ResourceDictionary theme)\n",{"type":43,"tag":781,"props":1674,"children":1675},{"class":783,"line":811},[1676],{"type":43,"tag":781,"props":1677,"children":1678},{},[1679],{"type":49,"value":1445},{"type":43,"tag":781,"props":1681,"children":1682},{"class":783,"line":821},[1683],{"type":43,"tag":781,"props":1684,"children":1685},{},[1686],{"type":49,"value":1687},"    var merged = Application.Current!.Resources.MergedDictionaries;\n",{"type":43,"tag":781,"props":1689,"children":1690},{"class":783,"line":830},[1691],{"type":43,"tag":781,"props":1692,"children":1693},{"emptyLinePlaceholder":815},[1694],{"type":49,"value":818},{"type":43,"tag":781,"props":1696,"children":1697},{"class":783,"line":839},[1698],{"type":43,"tag":781,"props":1699,"children":1700},{},[1701],{"type":49,"value":1702},"    \u002F\u002F ✅ Remove ONLY the previous theme — Colors.xaml \u002F Styles.xaml survive\n",{"type":43,"tag":781,"props":1704,"children":1705},{"class":783,"line":848},[1706],{"type":43,"tag":781,"props":1707,"children":1708},{},[1709],{"type":49,"value":1710},"    if (_currentTheme is not null)\n",{"type":43,"tag":781,"props":1712,"children":1713},{"class":783,"line":857},[1714],{"type":43,"tag":781,"props":1715,"children":1716},{},[1717],{"type":49,"value":1718},"        merged.Remove(_currentTheme);\n",{"type":43,"tag":781,"props":1720,"children":1721},{"class":783,"line":866},[1722],{"type":43,"tag":781,"props":1723,"children":1724},{"emptyLinePlaceholder":815},[1725],{"type":49,"value":818},{"type":43,"tag":781,"props":1727,"children":1728},{"class":783,"line":874},[1729],{"type":43,"tag":781,"props":1730,"children":1731},{},[1732],{"type":49,"value":1733},"    merged.Add(theme);\n",{"type":43,"tag":781,"props":1735,"children":1736},{"class":783,"line":883},[1737],{"type":43,"tag":781,"props":1738,"children":1739},{},[1740],{"type":49,"value":1741},"    _currentTheme = theme;\n",{"type":43,"tag":781,"props":1743,"children":1744},{"class":783,"line":892},[1745],{"type":43,"tag":781,"props":1746,"children":1747},{},[1748],{"type":49,"value":1461},{"type":43,"tag":781,"props":1750,"children":1751},{"class":783,"line":901},[1752],{"type":43,"tag":781,"props":1753,"children":1754},{"emptyLinePlaceholder":815},[1755],{"type":49,"value":818},{"type":43,"tag":781,"props":1757,"children":1758},{"class":783,"line":910},[1759],{"type":43,"tag":781,"props":1760,"children":1761},{},[1762],{"type":49,"value":1763},"\u002F\u002F Usage\n",{"type":43,"tag":781,"props":1765,"children":1766},{"class":783,"line":919},[1767],{"type":43,"tag":781,"props":1768,"children":1769},{},[1770],{"type":49,"value":1771},"ApplyTheme(new DarkTheme());\n",{"type":43,"tag":770,"props":1773,"children":1775},{"className":1140,"code":1774,"language":1142,"meta":775,"style":775},"\u002F\u002F ❌ Destroys the app's Colors.xaml and Styles.xaml along with the old theme\nvar merged = Application.Current!.Resources.MergedDictionaries;\nmerged.Clear();\nmerged.Add(theme);\n",[1776],{"type":43,"tag":147,"props":1777,"children":1778},{"__ignoreMap":775},[1779,1787,1795,1803],{"type":43,"tag":781,"props":1780,"children":1781},{"class":783,"line":784},[1782],{"type":43,"tag":781,"props":1783,"children":1784},{},[1785],{"type":49,"value":1786},"\u002F\u002F ❌ Destroys the app's Colors.xaml and Styles.xaml along with the old theme\n",{"type":43,"tag":781,"props":1788,"children":1789},{"class":783,"line":793},[1790],{"type":43,"tag":781,"props":1791,"children":1792},{},[1793],{"type":49,"value":1794},"var merged = Application.Current!.Resources.MergedDictionaries;\n",{"type":43,"tag":781,"props":1796,"children":1797},{"class":783,"line":802},[1798],{"type":43,"tag":781,"props":1799,"children":1800},{},[1801],{"type":49,"value":1802},"merged.Clear();\n",{"type":43,"tag":781,"props":1804,"children":1805},{"class":783,"line":811},[1806],{"type":43,"tag":781,"props":1807,"children":1808},{},[1809],{"type":49,"value":1810},"merged.Add(theme);\n",{"type":43,"tag":58,"props":1812,"children":1814},{"id":1813},"system-theme-detection",[1815],{"type":49,"value":1816},"System Theme Detection",{"type":43,"tag":743,"props":1818,"children":1820},{"id":1819},"read-the-current-theme",[1821],{"type":49,"value":1822},"Read the Current Theme",{"type":43,"tag":770,"props":1824,"children":1826},{"className":1140,"code":1825,"language":1142,"meta":775,"style":775},"AppTheme currentTheme = Application.Current!.RequestedTheme;\n\u002F\u002F Returns AppTheme.Light, AppTheme.Dark, or AppTheme.Unspecified\n",[1827],{"type":43,"tag":147,"props":1828,"children":1829},{"__ignoreMap":775},[1830,1838],{"type":43,"tag":781,"props":1831,"children":1832},{"class":783,"line":784},[1833],{"type":43,"tag":781,"props":1834,"children":1835},{},[1836],{"type":49,"value":1837},"AppTheme currentTheme = Application.Current!.RequestedTheme;\n",{"type":43,"tag":781,"props":1839,"children":1840},{"class":783,"line":793},[1841],{"type":43,"tag":781,"props":1842,"children":1843},{},[1844],{"type":49,"value":1845},"\u002F\u002F Returns AppTheme.Light, AppTheme.Dark, or AppTheme.Unspecified\n",{"type":43,"tag":743,"props":1847,"children":1849},{"id":1848},"override-the-system-theme",[1850],{"type":49,"value":1851},"Override the System Theme",{"type":43,"tag":770,"props":1853,"children":1855},{"className":1140,"code":1854,"language":1142,"meta":775,"style":775},"\u002F\u002F Force dark mode regardless of OS setting\nApplication.Current!.UserAppTheme = AppTheme.Dark;\n\n\u002F\u002F Reset to follow system theme\nApplication.Current!.UserAppTheme = AppTheme.Unspecified;\n",[1856],{"type":43,"tag":147,"props":1857,"children":1858},{"__ignoreMap":775},[1859,1867,1875,1882,1890],{"type":43,"tag":781,"props":1860,"children":1861},{"class":783,"line":784},[1862],{"type":43,"tag":781,"props":1863,"children":1864},{},[1865],{"type":49,"value":1866},"\u002F\u002F Force dark mode regardless of OS setting\n",{"type":43,"tag":781,"props":1868,"children":1869},{"class":783,"line":793},[1870],{"type":43,"tag":781,"props":1871,"children":1872},{},[1873],{"type":49,"value":1874},"Application.Current!.UserAppTheme = AppTheme.Dark;\n",{"type":43,"tag":781,"props":1876,"children":1877},{"class":783,"line":802},[1878],{"type":43,"tag":781,"props":1879,"children":1880},{"emptyLinePlaceholder":815},[1881],{"type":49,"value":818},{"type":43,"tag":781,"props":1883,"children":1884},{"class":783,"line":811},[1885],{"type":43,"tag":781,"props":1886,"children":1887},{},[1888],{"type":49,"value":1889},"\u002F\u002F Reset to follow system theme\n",{"type":43,"tag":781,"props":1891,"children":1892},{"class":783,"line":821},[1893],{"type":43,"tag":781,"props":1894,"children":1895},{},[1896],{"type":49,"value":1897},"Application.Current!.UserAppTheme = AppTheme.Unspecified;\n",{"type":43,"tag":743,"props":1899,"children":1901},{"id":1900},"react-to-theme-changes",[1902],{"type":49,"value":1903},"React to Theme Changes",{"type":43,"tag":770,"props":1905,"children":1907},{"className":1140,"code":1906,"language":1142,"meta":775,"style":775},"Application.Current!.RequestedThemeChanged += (s, e) =>\n{\n    AppTheme newTheme = e.RequestedTheme;\n    \u002F\u002F Update UI or switch ResourceDictionaries\n};\n",[1908],{"type":43,"tag":147,"props":1909,"children":1910},{"__ignoreMap":775},[1911,1919,1926,1934,1942],{"type":43,"tag":781,"props":1912,"children":1913},{"class":783,"line":784},[1914],{"type":43,"tag":781,"props":1915,"children":1916},{},[1917],{"type":49,"value":1918},"Application.Current!.RequestedThemeChanged += (s, e) =>\n",{"type":43,"tag":781,"props":1920,"children":1921},{"class":783,"line":793},[1922],{"type":43,"tag":781,"props":1923,"children":1924},{},[1925],{"type":49,"value":1445},{"type":43,"tag":781,"props":1927,"children":1928},{"class":783,"line":802},[1929],{"type":43,"tag":781,"props":1930,"children":1931},{},[1932],{"type":49,"value":1933},"    AppTheme newTheme = e.RequestedTheme;\n",{"type":43,"tag":781,"props":1935,"children":1936},{"class":783,"line":811},[1937],{"type":43,"tag":781,"props":1938,"children":1939},{},[1940],{"type":49,"value":1941},"    \u002F\u002F Update UI or switch ResourceDictionaries\n",{"type":43,"tag":781,"props":1943,"children":1944},{"class":783,"line":821},[1945],{"type":43,"tag":781,"props":1946,"children":1947},{},[1948],{"type":49,"value":1949},"};\n",{"type":43,"tag":58,"props":1951,"children":1953},{"id":1952},"combining-both-approaches",[1954],{"type":49,"value":1955},"Combining Both Approaches",{"type":43,"tag":52,"props":1957,"children":1958},{},[1959,1960,1965,1967,1972,1974,1979,1981,1986],{"type":49,"value":1484},{"type":43,"tag":147,"props":1961,"children":1963},{"className":1962},[],[1964],{"type":49,"value":204},{"type":49,"value":1966}," with ",{"type":43,"tag":147,"props":1968,"children":1970},{"className":1969},[],[1971],{"type":49,"value":225},{"type":49,"value":1973}," values for maximum flexibility — the\nnested ",{"type":43,"tag":147,"props":1975,"children":1977},{"className":1976},[],[1978],{"type":49,"value":225},{"type":49,"value":1980}," stays live, so swapping the dictionary updates the value\n",{"type":43,"tag":331,"props":1982,"children":1983},{},[1984],{"type":49,"value":1985},"and",{"type":49,"value":1987}," the OS light\u002Fdark switch is still honoured:",{"type":43,"tag":770,"props":1989,"children":1991},{"className":772,"code":1990,"language":774,"meta":775,"style":775},"\u003CLabel TextColor=\"{AppThemeBinding\n    Light={DynamicResource LightPrimary},\n    Dark={DynamicResource DarkPrimary}}\" \u002F>\n",[1992],{"type":43,"tag":147,"props":1993,"children":1994},{"__ignoreMap":775},[1995,2003,2011],{"type":43,"tag":781,"props":1996,"children":1997},{"class":783,"line":784},[1998],{"type":43,"tag":781,"props":1999,"children":2000},{},[2001],{"type":49,"value":2002},"\u003CLabel TextColor=\"{AppThemeBinding\n",{"type":43,"tag":781,"props":2004,"children":2005},{"class":783,"line":793},[2006],{"type":43,"tag":781,"props":2007,"children":2008},{},[2009],{"type":49,"value":2010},"    Light={DynamicResource LightPrimary},\n",{"type":43,"tag":781,"props":2012,"children":2013},{"class":783,"line":802},[2014],{"type":43,"tag":781,"props":2015,"children":2016},{},[2017],{"type":49,"value":2018},"    Dark={DynamicResource DarkPrimary}}\" \u002F>\n",{"type":43,"tag":52,"props":2020,"children":2021},{},[2022],{"type":49,"value":2023},"Or react to system changes and swap full dictionaries:",{"type":43,"tag":770,"props":2025,"children":2027},{"className":1140,"code":2026,"language":1142,"meta":775,"style":775},"Application.Current!.RequestedThemeChanged += (s, e) =>\n{\n    ApplyTheme(e.RequestedTheme == AppTheme.Dark\n        ? new DarkTheme()\n        : new LightTheme());\n};\n",[2028],{"type":43,"tag":147,"props":2029,"children":2030},{"__ignoreMap":775},[2031,2038,2045,2053,2061,2069],{"type":43,"tag":781,"props":2032,"children":2033},{"class":783,"line":784},[2034],{"type":43,"tag":781,"props":2035,"children":2036},{},[2037],{"type":49,"value":1918},{"type":43,"tag":781,"props":2039,"children":2040},{"class":783,"line":793},[2041],{"type":43,"tag":781,"props":2042,"children":2043},{},[2044],{"type":49,"value":1445},{"type":43,"tag":781,"props":2046,"children":2047},{"class":783,"line":802},[2048],{"type":43,"tag":781,"props":2049,"children":2050},{},[2051],{"type":49,"value":2052},"    ApplyTheme(e.RequestedTheme == AppTheme.Dark\n",{"type":43,"tag":781,"props":2054,"children":2055},{"class":783,"line":811},[2056],{"type":43,"tag":781,"props":2057,"children":2058},{},[2059],{"type":49,"value":2060},"        ? new DarkTheme()\n",{"type":43,"tag":781,"props":2062,"children":2063},{"class":783,"line":821},[2064],{"type":43,"tag":781,"props":2065,"children":2066},{},[2067],{"type":49,"value":2068},"        : new LightTheme());\n",{"type":43,"tag":781,"props":2070,"children":2071},{"class":783,"line":830},[2072],{"type":43,"tag":781,"props":2073,"children":2074},{},[2075],{"type":49,"value":1949},{"type":43,"tag":58,"props":2077,"children":2079},{"id":2078},"saving-and-restoring-user-preference",[2080],{"type":49,"value":2081},"Saving and Restoring User Preference",{"type":43,"tag":52,"props":2083,"children":2084},{},[2085,2087,2093],{"type":49,"value":2086},"Store the user's choice with ",{"type":43,"tag":147,"props":2088,"children":2090},{"className":2089},[],[2091],{"type":49,"value":2092},"Preferences",{"type":49,"value":2094}," and apply it on startup:",{"type":43,"tag":770,"props":2096,"children":2098},{"className":1140,"code":2097,"language":1142,"meta":775,"style":775},"\u002F\u002F Save choice\nPreferences.Set(\"AppTheme\", \"Dark\");\n\n\u002F\u002F Restore on startup (in App constructor or CreateWindow)\nvar saved = Preferences.Get(\"AppTheme\", \"System\");\nApplication.Current!.UserAppTheme = saved switch\n{\n    \"Light\" => AppTheme.Light,\n    \"Dark\"  => AppTheme.Dark,\n    _       => AppTheme.Unspecified\n};\n",[2099],{"type":43,"tag":147,"props":2100,"children":2101},{"__ignoreMap":775},[2102,2110,2118,2125,2133,2141,2149,2156,2164,2172,2180],{"type":43,"tag":781,"props":2103,"children":2104},{"class":783,"line":784},[2105],{"type":43,"tag":781,"props":2106,"children":2107},{},[2108],{"type":49,"value":2109},"\u002F\u002F Save choice\n",{"type":43,"tag":781,"props":2111,"children":2112},{"class":783,"line":793},[2113],{"type":43,"tag":781,"props":2114,"children":2115},{},[2116],{"type":49,"value":2117},"Preferences.Set(\"AppTheme\", \"Dark\");\n",{"type":43,"tag":781,"props":2119,"children":2120},{"class":783,"line":802},[2121],{"type":43,"tag":781,"props":2122,"children":2123},{"emptyLinePlaceholder":815},[2124],{"type":49,"value":818},{"type":43,"tag":781,"props":2126,"children":2127},{"class":783,"line":811},[2128],{"type":43,"tag":781,"props":2129,"children":2130},{},[2131],{"type":49,"value":2132},"\u002F\u002F Restore on startup (in App constructor or CreateWindow)\n",{"type":43,"tag":781,"props":2134,"children":2135},{"class":783,"line":821},[2136],{"type":43,"tag":781,"props":2137,"children":2138},{},[2139],{"type":49,"value":2140},"var saved = Preferences.Get(\"AppTheme\", \"System\");\n",{"type":43,"tag":781,"props":2142,"children":2143},{"class":783,"line":830},[2144],{"type":43,"tag":781,"props":2145,"children":2146},{},[2147],{"type":49,"value":2148},"Application.Current!.UserAppTheme = saved switch\n",{"type":43,"tag":781,"props":2150,"children":2151},{"class":783,"line":839},[2152],{"type":43,"tag":781,"props":2153,"children":2154},{},[2155],{"type":49,"value":1445},{"type":43,"tag":781,"props":2157,"children":2158},{"class":783,"line":848},[2159],{"type":43,"tag":781,"props":2160,"children":2161},{},[2162],{"type":49,"value":2163},"    \"Light\" => AppTheme.Light,\n",{"type":43,"tag":781,"props":2165,"children":2166},{"class":783,"line":857},[2167],{"type":43,"tag":781,"props":2168,"children":2169},{},[2170],{"type":49,"value":2171},"    \"Dark\"  => AppTheme.Dark,\n",{"type":43,"tag":781,"props":2173,"children":2174},{"class":783,"line":866},[2175],{"type":43,"tag":781,"props":2176,"children":2177},{},[2178],{"type":49,"value":2179},"    _       => AppTheme.Unspecified\n",{"type":43,"tag":781,"props":2181,"children":2182},{"class":783,"line":874},[2183],{"type":43,"tag":781,"props":2184,"children":2185},{},[2186],{"type":49,"value":1949},{"type":43,"tag":58,"props":2188,"children":2190},{"id":2189},"common-pitfalls",[2191],{"type":49,"value":2192},"Common Pitfalls",{"type":43,"tag":743,"props":2194,"children":2196},{"id":2195},"android-configchangesuimode-is-required",[2197],{"type":49,"value":2198},"Android: ConfigChanges.UiMode is Required",{"type":43,"tag":52,"props":2200,"children":2201},{},[2202,2207,2208,2213,2215,2220],{"type":43,"tag":147,"props":2203,"children":2205},{"className":2204},[],[2206],{"type":49,"value":295},{"type":49,"value":375},{"type":43,"tag":315,"props":2209,"children":2210},{},[2211],{"type":49,"value":2212},"must",{"type":49,"value":2214}," include ",{"type":43,"tag":147,"props":2216,"children":2218},{"className":2217},[],[2219],{"type":49,"value":287},{"type":49,"value":2221}," or theme-change events will not fire and the activity restarts instead of handling the change gracefully:",{"type":43,"tag":770,"props":2223,"children":2225},{"className":1140,"code":2224,"language":1142,"meta":775,"style":775},"[Activity(Theme = \"@style\u002FMaui.SplashTheme\",\n          MainLauncher = true,\n          ConfigurationChanges = ConfigChanges.ScreenSize\n                               | ConfigChanges.Orientation\n                               | ConfigChanges.UiMode  \u002F\u002F ← Required for theme detection\n                               | ConfigChanges.ScreenLayout\n                               | ConfigChanges.SmallestScreenSize\n                               | ConfigChanges.Density)]\npublic class MainActivity : MauiAppCompatActivity { }\n",[2226],{"type":43,"tag":147,"props":2227,"children":2228},{"__ignoreMap":775},[2229,2237,2245,2253,2261,2269,2277,2285,2293],{"type":43,"tag":781,"props":2230,"children":2231},{"class":783,"line":784},[2232],{"type":43,"tag":781,"props":2233,"children":2234},{},[2235],{"type":49,"value":2236},"[Activity(Theme = \"@style\u002FMaui.SplashTheme\",\n",{"type":43,"tag":781,"props":2238,"children":2239},{"class":783,"line":793},[2240],{"type":43,"tag":781,"props":2241,"children":2242},{},[2243],{"type":49,"value":2244},"          MainLauncher = true,\n",{"type":43,"tag":781,"props":2246,"children":2247},{"class":783,"line":802},[2248],{"type":43,"tag":781,"props":2249,"children":2250},{},[2251],{"type":49,"value":2252},"          ConfigurationChanges = ConfigChanges.ScreenSize\n",{"type":43,"tag":781,"props":2254,"children":2255},{"class":783,"line":811},[2256],{"type":43,"tag":781,"props":2257,"children":2258},{},[2259],{"type":49,"value":2260},"                               | ConfigChanges.Orientation\n",{"type":43,"tag":781,"props":2262,"children":2263},{"class":783,"line":821},[2264],{"type":43,"tag":781,"props":2265,"children":2266},{},[2267],{"type":49,"value":2268},"                               | ConfigChanges.UiMode  \u002F\u002F ← Required for theme detection\n",{"type":43,"tag":781,"props":2270,"children":2271},{"class":783,"line":830},[2272],{"type":43,"tag":781,"props":2273,"children":2274},{},[2275],{"type":49,"value":2276},"                               | ConfigChanges.ScreenLayout\n",{"type":43,"tag":781,"props":2278,"children":2279},{"class":783,"line":839},[2280],{"type":43,"tag":781,"props":2281,"children":2282},{},[2283],{"type":49,"value":2284},"                               | ConfigChanges.SmallestScreenSize\n",{"type":43,"tag":781,"props":2286,"children":2287},{"class":783,"line":848},[2288],{"type":43,"tag":781,"props":2289,"children":2290},{},[2291],{"type":49,"value":2292},"                               | ConfigChanges.Density)]\n",{"type":43,"tag":781,"props":2294,"children":2295},{"class":783,"line":857},[2296],{"type":43,"tag":781,"props":2297,"children":2298},{},[2299],{"type":49,"value":2300},"public class MainActivity : MauiAppCompatActivity { }\n",{"type":43,"tag":52,"props":2302,"children":2303},{},[2304,2306,2311,2313,2318],{"type":49,"value":2305},"Without ",{"type":43,"tag":147,"props":2307,"children":2309},{"className":2308},[],[2310],{"type":49,"value":327},{"type":49,"value":2312},", toggling dark mode in Android settings causes a full activity restart — losing navigation state and appearing as a crash. With it declared, the app stays alive and ",{"type":43,"tag":147,"props":2314,"children":2316},{"className":2315},[],[2317],{"type":49,"value":253},{"type":49,"value":2319}," fires, so pair this fix with a handler that re-applies the theme (see below).",{"type":43,"tag":743,"props":2321,"children":2323},{"id":2322},"dynamicresource-vs-staticresource",[2324],{"type":49,"value":2325},"DynamicResource vs StaticResource",{"type":43,"tag":52,"props":2327,"children":2328},{},[2329,2331,2335,2337,2342],{"type":49,"value":2330},"When using ResourceDictionary theme switching, you ",{"type":43,"tag":315,"props":2332,"children":2333},{},[2334],{"type":49,"value":2212},{"type":49,"value":2336}," use ",{"type":43,"tag":147,"props":2338,"children":2340},{"className":2339},[],[2341],{"type":49,"value":225},{"type":49,"value":2343},":",{"type":43,"tag":770,"props":2345,"children":2347},{"className":772,"code":2346,"language":774,"meta":775,"style":775},"\u003C!-- ✅ Updates when theme dictionary changes -->\n\u003CLabel TextColor=\"{DynamicResource PrimaryTextColor}\" \u002F>\n\n\u003C!-- ❌ Frozen at first load — won't update on theme switch -->\n\u003CLabel TextColor=\"{StaticResource PrimaryTextColor}\" \u002F>\n",[2348],{"type":43,"tag":147,"props":2349,"children":2350},{"__ignoreMap":775},[2351,2359,2367,2374,2382],{"type":43,"tag":781,"props":2352,"children":2353},{"class":783,"line":784},[2354],{"type":43,"tag":781,"props":2355,"children":2356},{},[2357],{"type":49,"value":2358},"\u003C!-- ✅ Updates when theme dictionary changes -->\n",{"type":43,"tag":781,"props":2360,"children":2361},{"class":783,"line":793},[2362],{"type":43,"tag":781,"props":2363,"children":2364},{},[2365],{"type":49,"value":2366},"\u003CLabel TextColor=\"{DynamicResource PrimaryTextColor}\" \u002F>\n",{"type":43,"tag":781,"props":2368,"children":2369},{"class":783,"line":802},[2370],{"type":43,"tag":781,"props":2371,"children":2372},{"emptyLinePlaceholder":815},[2373],{"type":49,"value":818},{"type":43,"tag":781,"props":2375,"children":2376},{"class":783,"line":811},[2377],{"type":43,"tag":781,"props":2378,"children":2379},{},[2380],{"type":49,"value":2381},"\u003C!-- ❌ Frozen at first load — won't update on theme switch -->\n",{"type":43,"tag":781,"props":2383,"children":2384},{"class":783,"line":821},[2385],{"type":43,"tag":781,"props":2386,"children":2387},{},[2388],{"type":49,"value":2389},"\u003CLabel TextColor=\"{StaticResource PrimaryTextColor}\" \u002F>\n",{"type":43,"tag":52,"props":2391,"children":2392},{},[2393,2398],{"type":43,"tag":147,"props":2394,"children":2396},{"className":2395},[],[2397],{"type":49,"value":225},{"type":49,"value":2399}," only helps if something actually swaps the dictionary. When you\ndiagnose this, always show the swap and the system-theme hook alongside the fix —\notherwise the user has a corrected binding that still never updates:",{"type":43,"tag":770,"props":2401,"children":2403},{"className":1140,"code":2402,"language":1142,"meta":775,"style":775},"static ResourceDictionary? _currentTheme;\n\nvoid ApplyTheme(bool useDark)\n{\n    var merged = Application.Current!.Resources.MergedDictionaries;\n\n    \u002F\u002F Remove only the previous theme — never Clear(), which also wipes\n    \u002F\u002F the template's Colors.xaml \u002F Styles.xaml\n    if (_currentTheme is not null)\n        merged.Remove(_currentTheme);\n\n    _currentTheme = useDark ? new DarkTheme() : new LightTheme();\n    merged.Add(_currentTheme);\n}\n\n\u002F\u002F React to the OS switching light\u002Fdark\nApplication.Current!.RequestedThemeChanged += (s, e) =>\n    ApplyTheme(e.RequestedTheme == AppTheme.Dark);\n",[2404],{"type":43,"tag":147,"props":2405,"children":2406},{"__ignoreMap":775},[2407,2414,2421,2429,2436,2443,2450,2458,2466,2473,2480,2487,2495,2503,2510,2517,2525,2532],{"type":43,"tag":781,"props":2408,"children":2409},{"class":783,"line":784},[2410],{"type":43,"tag":781,"props":2411,"children":2412},{},[2413],{"type":49,"value":1657},{"type":43,"tag":781,"props":2415,"children":2416},{"class":783,"line":793},[2417],{"type":43,"tag":781,"props":2418,"children":2419},{"emptyLinePlaceholder":815},[2420],{"type":49,"value":818},{"type":43,"tag":781,"props":2422,"children":2423},{"class":783,"line":802},[2424],{"type":43,"tag":781,"props":2425,"children":2426},{},[2427],{"type":49,"value":2428},"void ApplyTheme(bool useDark)\n",{"type":43,"tag":781,"props":2430,"children":2431},{"class":783,"line":811},[2432],{"type":43,"tag":781,"props":2433,"children":2434},{},[2435],{"type":49,"value":1445},{"type":43,"tag":781,"props":2437,"children":2438},{"class":783,"line":821},[2439],{"type":43,"tag":781,"props":2440,"children":2441},{},[2442],{"type":49,"value":1687},{"type":43,"tag":781,"props":2444,"children":2445},{"class":783,"line":830},[2446],{"type":43,"tag":781,"props":2447,"children":2448},{"emptyLinePlaceholder":815},[2449],{"type":49,"value":818},{"type":43,"tag":781,"props":2451,"children":2452},{"class":783,"line":839},[2453],{"type":43,"tag":781,"props":2454,"children":2455},{},[2456],{"type":49,"value":2457},"    \u002F\u002F Remove only the previous theme — never Clear(), which also wipes\n",{"type":43,"tag":781,"props":2459,"children":2460},{"class":783,"line":848},[2461],{"type":43,"tag":781,"props":2462,"children":2463},{},[2464],{"type":49,"value":2465},"    \u002F\u002F the template's Colors.xaml \u002F Styles.xaml\n",{"type":43,"tag":781,"props":2467,"children":2468},{"class":783,"line":857},[2469],{"type":43,"tag":781,"props":2470,"children":2471},{},[2472],{"type":49,"value":1710},{"type":43,"tag":781,"props":2474,"children":2475},{"class":783,"line":866},[2476],{"type":43,"tag":781,"props":2477,"children":2478},{},[2479],{"type":49,"value":1718},{"type":43,"tag":781,"props":2481,"children":2482},{"class":783,"line":874},[2483],{"type":43,"tag":781,"props":2484,"children":2485},{"emptyLinePlaceholder":815},[2486],{"type":49,"value":818},{"type":43,"tag":781,"props":2488,"children":2489},{"class":783,"line":883},[2490],{"type":43,"tag":781,"props":2491,"children":2492},{},[2493],{"type":49,"value":2494},"    _currentTheme = useDark ? new DarkTheme() : new LightTheme();\n",{"type":43,"tag":781,"props":2496,"children":2497},{"class":783,"line":892},[2498],{"type":43,"tag":781,"props":2499,"children":2500},{},[2501],{"type":49,"value":2502},"    merged.Add(_currentTheme);\n",{"type":43,"tag":781,"props":2504,"children":2505},{"class":783,"line":901},[2506],{"type":43,"tag":781,"props":2507,"children":2508},{},[2509],{"type":49,"value":1461},{"type":43,"tag":781,"props":2511,"children":2512},{"class":783,"line":910},[2513],{"type":43,"tag":781,"props":2514,"children":2515},{"emptyLinePlaceholder":815},[2516],{"type":49,"value":818},{"type":43,"tag":781,"props":2518,"children":2519},{"class":783,"line":919},[2520],{"type":43,"tag":781,"props":2521,"children":2522},{},[2523],{"type":49,"value":2524},"\u002F\u002F React to the OS switching light\u002Fdark\n",{"type":43,"tag":781,"props":2526,"children":2527},{"class":783,"line":928},[2528],{"type":43,"tag":781,"props":2529,"children":2530},{},[2531],{"type":49,"value":1918},{"type":43,"tag":781,"props":2533,"children":2534},{"class":783,"line":936},[2535],{"type":43,"tag":781,"props":2536,"children":2537},{},[2538],{"type":49,"value":2539},"    ApplyTheme(e.RequestedTheme == AppTheme.Dark);\n",{"type":43,"tag":743,"props":2541,"children":2543},{"id":2542},"hardcoded-colors-break-theming",[2544],{"type":49,"value":2545},"Hardcoded Colors Break Theming",{"type":43,"tag":52,"props":2547,"children":2548},{},[2549],{"type":49,"value":2550},"Avoid inline color values on elements that should respect the theme:",{"type":43,"tag":770,"props":2552,"children":2554},{"className":772,"code":2553,"language":774,"meta":775,"style":775},"\u003C!-- ❌ Will not change with theme -->\n\u003CLabel TextColor=\"#333333\" \u002F>\n\n\u003C!-- ✅ Theme-aware -->\n\u003CLabel TextColor=\"{DynamicResource PrimaryTextColor}\" \u002F>\n",[2555],{"type":43,"tag":147,"props":2556,"children":2557},{"__ignoreMap":775},[2558,2566,2574,2581,2589],{"type":43,"tag":781,"props":2559,"children":2560},{"class":783,"line":784},[2561],{"type":43,"tag":781,"props":2562,"children":2563},{},[2564],{"type":49,"value":2565},"\u003C!-- ❌ Will not change with theme -->\n",{"type":43,"tag":781,"props":2567,"children":2568},{"class":783,"line":793},[2569],{"type":43,"tag":781,"props":2570,"children":2571},{},[2572],{"type":49,"value":2573},"\u003CLabel TextColor=\"#333333\" \u002F>\n",{"type":43,"tag":781,"props":2575,"children":2576},{"class":783,"line":802},[2577],{"type":43,"tag":781,"props":2578,"children":2579},{"emptyLinePlaceholder":815},[2580],{"type":49,"value":818},{"type":43,"tag":781,"props":2582,"children":2583},{"class":783,"line":811},[2584],{"type":43,"tag":781,"props":2585,"children":2586},{},[2587],{"type":49,"value":2588},"\u003C!-- ✅ Theme-aware -->\n",{"type":43,"tag":781,"props":2590,"children":2591},{"class":783,"line":821},[2592],{"type":43,"tag":781,"props":2593,"children":2594},{},[2595],{"type":49,"value":2366},{"type":43,"tag":743,"props":2597,"children":2599},{"id":2598},"css-themes-cannot-be-swapped-at-runtime",[2600],{"type":49,"value":2601},"CSS Themes Cannot Be Swapped at Runtime",{"type":43,"tag":52,"props":2603,"children":2604},{},[2605,2607,2612],{"type":49,"value":2606},".NET MAUI supports CSS styling, but CSS-based themes ",{"type":43,"tag":315,"props":2608,"children":2609},{},[2610],{"type":49,"value":2611},"cannot be swapped dynamically",{"type":49,"value":2613},". Use ResourceDictionary theming for runtime switching.",{"type":43,"tag":743,"props":2615,"children":2617},{"id":2616},"theme-keys-must-match-across-dictionaries",[2618],{"type":49,"value":2619},"Theme Keys Must Match Across Dictionaries",{"type":43,"tag":52,"props":2621,"children":2622},{},[2623,2625,2631],{"type":49,"value":2624},"Every ",{"type":43,"tag":147,"props":2626,"children":2628},{"className":2627},[],[2629],{"type":49,"value":2630},"x:Key",{"type":49,"value":2632}," used in one theme dictionary must exist in all other theme dictionaries. A missing key causes a silent fallback to the default value, leading to inconsistent appearance.",{"type":43,"tag":58,"props":2634,"children":2636},{"id":2635},"platform-support",[2637],{"type":49,"value":2638},"Platform Support",{"type":43,"tag":393,"props":2640,"children":2641},{},[2642,2658],{"type":43,"tag":397,"props":2643,"children":2644},{},[2645],{"type":43,"tag":401,"props":2646,"children":2647},{},[2648,2653],{"type":43,"tag":405,"props":2649,"children":2650},{},[2651],{"type":49,"value":2652},"Platform",{"type":43,"tag":405,"props":2654,"children":2655},{},[2656],{"type":49,"value":2657},"Minimum Version",{"type":43,"tag":426,"props":2659,"children":2660},{},[2661,2674,2687,2700],{"type":43,"tag":401,"props":2662,"children":2663},{},[2664,2669],{"type":43,"tag":433,"props":2665,"children":2666},{},[2667],{"type":49,"value":2668},"iOS",{"type":43,"tag":433,"props":2670,"children":2671},{},[2672],{"type":49,"value":2673},"13+",{"type":43,"tag":401,"props":2675,"children":2676},{},[2677,2682],{"type":43,"tag":433,"props":2678,"children":2679},{},[2680],{"type":49,"value":2681},"Android",{"type":43,"tag":433,"props":2683,"children":2684},{},[2685],{"type":49,"value":2686},"10+ (API 29)",{"type":43,"tag":401,"props":2688,"children":2689},{},[2690,2695],{"type":43,"tag":433,"props":2691,"children":2692},{},[2693],{"type":49,"value":2694},"macOS Catalyst",{"type":43,"tag":433,"props":2696,"children":2697},{},[2698],{"type":49,"value":2699},"10.15+",{"type":43,"tag":401,"props":2701,"children":2702},{},[2703,2708],{"type":43,"tag":433,"props":2704,"children":2705},{},[2706],{"type":49,"value":2707},"Windows",{"type":43,"tag":433,"props":2709,"children":2710},{},[2711],{"type":49,"value":2712},"10+",{"type":43,"tag":58,"props":2714,"children":2716},{"id":2715},"quick-reference",[2717],{"type":49,"value":2718},"Quick Reference",{"type":43,"tag":65,"props":2720,"children":2721},{},[2722,2739,2761,2775,2789,2805,2847,2873],{"type":43,"tag":69,"props":2723,"children":2724},{},[2725,2730,2732,2737],{"type":43,"tag":315,"props":2726,"children":2727},{},[2728],{"type":49,"value":2729},"OS light\u002Fdark",{"type":49,"value":2731}," → ",{"type":43,"tag":147,"props":2733,"children":2735},{"className":2734},[],[2736],{"type":49,"value":204},{"type":49,"value":2738}," markup extension",{"type":43,"tag":69,"props":2740,"children":2741},{},[2742,2747,2748,2754,2755],{"type":43,"tag":315,"props":2743,"children":2744},{},[2745],{"type":49,"value":2746},"Theme colors in C#",{"type":49,"value":2731},{"type":43,"tag":147,"props":2749,"children":2751},{"className":2750},[],[2752],{"type":49,"value":2753},"SetAppThemeColor()",{"type":49,"value":725},{"type":43,"tag":147,"props":2756,"children":2758},{"className":2757},[],[2759],{"type":49,"value":2760},"SetAppTheme\u003CT>()",{"type":43,"tag":69,"props":2762,"children":2763},{},[2764,2769,2770],{"type":43,"tag":315,"props":2765,"children":2766},{},[2767],{"type":49,"value":2768},"Read OS theme",{"type":49,"value":2731},{"type":43,"tag":147,"props":2771,"children":2773},{"className":2772},[],[2774],{"type":49,"value":245},{"type":43,"tag":69,"props":2776,"children":2777},{},[2778,2783,2784],{"type":43,"tag":315,"props":2779,"children":2780},{},[2781],{"type":49,"value":2782},"Force theme",{"type":49,"value":2731},{"type":43,"tag":147,"props":2785,"children":2787},{"className":2786},[],[2788],{"type":49,"value":559},{"type":43,"tag":69,"props":2790,"children":2791},{},[2792,2797,2798,2803],{"type":43,"tag":315,"props":2793,"children":2794},{},[2795],{"type":49,"value":2796},"Theme changes",{"type":49,"value":2731},{"type":43,"tag":147,"props":2799,"children":2801},{"className":2800},[],[2802],{"type":49,"value":253},{"type":49,"value":2804}," event",{"type":43,"tag":69,"props":2806,"children":2807},{},[2808,2813,2814,2820,2822,2827,2829,2835,2837],{"type":43,"tag":315,"props":2809,"children":2810},{},[2811],{"type":49,"value":2812},"Custom switching",{"type":49,"value":2731},{"type":43,"tag":147,"props":2815,"children":2817},{"className":2816},[],[2818],{"type":49,"value":2819},"Remove",{"type":49,"value":2821}," the old theme from ",{"type":43,"tag":147,"props":2823,"children":2825},{"className":2824},[],[2826],{"type":49,"value":1627},{"type":49,"value":2828},", then ",{"type":43,"tag":147,"props":2830,"children":2832},{"className":2831},[],[2833],{"type":49,"value":2834},"Add",{"type":49,"value":2836}," the new one — ",{"type":43,"tag":315,"props":2838,"children":2839},{},[2840,2842],{"type":49,"value":2841},"never ",{"type":43,"tag":147,"props":2843,"children":2845},{"className":2844},[],[2846],{"type":49,"value":1606},{"type":43,"tag":69,"props":2848,"children":2849},{},[2850,2855,2856,2864,2866,2871],{"type":43,"tag":315,"props":2851,"children":2852},{},[2853],{"type":49,"value":2854},"Runtime bindings",{"type":49,"value":2731},{"type":43,"tag":315,"props":2857,"children":2858},{},[2859],{"type":43,"tag":147,"props":2860,"children":2862},{"className":2861},[],[2863],{"type":49,"value":225},{"type":49,"value":2865}," (not ",{"type":43,"tag":147,"props":2867,"children":2869},{"className":2868},[],[2870],{"type":49,"value":467},{"type":49,"value":2872},")",{"type":43,"tag":69,"props":2874,"children":2875},{},[2876,2881,2882,2887,2888],{"type":43,"tag":315,"props":2877,"children":2878},{},[2879],{"type":49,"value":2880},"Persist choice",{"type":49,"value":2731},{"type":43,"tag":147,"props":2883,"children":2885},{"className":2884},[],[2886],{"type":49,"value":266},{"type":49,"value":268},{"type":43,"tag":147,"props":2889,"children":2891},{"className":2890},[],[2892],{"type":49,"value":274},{"type":43,"tag":2894,"props":2895,"children":2896},"style",{},[2897],{"type":49,"value":2898},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"items":2900,"total":3062},[2901,2917,2932,2946,2963,2977,2996,3006,3018,3028,3041,3052],{"slug":2902,"name":2902,"fn":2903,"description":2904,"org":2905,"tags":2906,"stars":2914,"repoUrl":2915,"updatedAt":2916},"multithreaded-task-migration","migrate MSBuild tasks to multithreaded mode","Guide for migrating MSBuild tasks to multithreaded mode support, including compatibility red-team review. Use this when converting tasks to thread-safe versions, implementing IMultiThreadableTask, adding TaskEnvironment support, or auditing migrations for behavioral compatibility.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2907,2908,2911],{"name":17,"slug":18,"type":15},{"name":2909,"slug":2910,"type":15},"Engineering","engineering",{"name":2912,"slug":2913,"type":15},"Performance","performance",5535,"https:\u002F\u002Fgithub.com\u002Fdotnet\u002Fmsbuild","2026-07-22T05:37:33.965588",{"slug":2918,"name":2918,"fn":2919,"description":2920,"org":2921,"tags":2922,"stars":25,"repoUrl":26,"updatedAt":2931},"analyzing-dotnet-performance","analyze .NET code for performance anti-patterns","Scans .NET code for ~50 performance anti-patterns across async, memory, strings, collections, LINQ, regex, serialization, and I\u002FO with tiered severity classification. Use when analyzing .NET code for optimization opportunities, reviewing hot paths, or auditing allocation-heavy patterns.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2923,2924,2927,2930],{"name":17,"slug":18,"type":15},{"name":2925,"slug":2926,"type":15},"Code Analysis","code-analysis",{"name":2928,"slug":2929,"type":15},"Debugging","debugging",{"name":2912,"slug":2913,"type":15},"2026-07-12T08:23:25.400375",{"slug":2933,"name":2933,"fn":2934,"description":2935,"org":2936,"tags":2937,"stars":25,"repoUrl":26,"updatedAt":2945},"android-tombstone-symbolication","symbolicate .NET runtime frames in Android tombstones","Symbolicate the .NET runtime frames in an Android tombstone file. Extracts BuildIds and PC offsets from the native backtrace, downloads debug symbols from the Microsoft symbol server, and runs llvm-symbolizer to produce function names with source file and line numbers. USE FOR triaging a .NET MAUI or Mono Android app crash from a tombstone, resolving native backtrace frames in libmonosgen-2.0.so or libcoreclr.so to .NET runtime source code, or investigating SIGABRT, SIGSEGV, or other native signals originating from the .NET runtime on Android. DO NOT USE FOR pure Java\u002FKotlin crashes, managed .NET exceptions that are already captured in logcat, or iOS crash logs. INVOKES Symbolicate-Tombstone.ps1 script, llvm-symbolizer, Microsoft symbol server.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2938,2939,2941,2942],{"name":17,"slug":18,"type":15},{"name":2681,"slug":2940,"type":15},"android",{"name":2928,"slug":2929,"type":15},{"name":2943,"slug":2944,"type":15},"Microsoft","microsoft","2026-07-12T08:23:21.595572",{"slug":2947,"name":2947,"fn":2948,"description":2949,"org":2950,"tags":2951,"stars":25,"repoUrl":26,"updatedAt":2962},"apple-crash-symbolication","symbolicate .NET runtime frames in crash logs","Symbolicate .NET runtime frames in Apple platform .ips crash logs (iOS, tvOS, Mac Catalyst, macOS). Extracts UUIDs and addresses from the native backtrace, locates dSYM debug symbols, and runs atos to produce function names with source file and line numbers. Automatically downloads .dwarf symbols from the Microsoft symbol server using Mach-O UUIDs. USE FOR triaging a .NET MAUI or Mono app crash from an .ips file on any Apple platform, resolving native backtrace frames in libcoreclr or libmonosgen-2.0 to .NET runtime source code, retrieving .ips crash logs from a connected iOS device or iPhone, or investigating EXC_CRASH, EXC_BAD_ACCESS, SIGABRT, or SIGSEGV originating from the .NET runtime. DO NOT USE FOR pure Swift\u002FObjective-C crashes with no .NET components, or Android tombstone files. INVOKES Symbolicate-Crash.ps1 script, atos, dwarfdump, idevicecrashreport.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2952,2953,2954,2956,2959],{"name":17,"slug":18,"type":15},{"name":2928,"slug":2929,"type":15},{"name":2668,"slug":2955,"type":15},"ios",{"name":2957,"slug":2958,"type":15},"macOS","macos",{"name":2960,"slug":2961,"type":15},"Observability","observability","2026-07-12T08:23:20.369986",{"slug":2964,"name":2964,"fn":2965,"description":2966,"org":2967,"tags":2968,"stars":25,"repoUrl":26,"updatedAt":2976},"assertion-quality","evaluate assertion quality in test suites","Analyzes the variety and depth of assertions across test suites in any language. Use when the user asks to evaluate assertion quality, find shallow tests, identify assertion-free tests (no assertions or only trivial ones like Assert.IsNotNull \u002F toBeTruthy()), flag self-referential or tautological assertions, measure assertion diversity, or audit whether tests verify different facets of behavior. Polyglot: .NET, Python, TS\u002FJS, Java, Go, Ruby, Rust, Swift, Kotlin, PowerShell, C++. DO NOT USE FOR: writing new tests (use code-testing-agent \u002F writing-mstest-tests), mutation reasoning about whether tests would catch a bug (use test-gap-analysis), or a general severity-ranked anti-pattern audit (use test-anti-patterns), fixing or rewriting assertions, or writing, fixing, or modernizing MSTest tests, assertions, or attributes (use writing-mstest-tests).",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2969,2970,2973],{"name":2925,"slug":2926,"type":15},{"name":2971,"slug":2972,"type":15},"QA","qa",{"name":2974,"slug":2975,"type":15},"Testing","testing","2026-07-12T08:23:51.277743",{"slug":2978,"name":2978,"fn":2979,"description":2980,"org":2981,"tags":2982,"stars":25,"repoUrl":26,"updatedAt":2995},"author-component","create and review Blazor components","Create or review Blazor components (.razor files) with correct architecture. USE FOR: writing new Blazor components that do NOT involve JavaScript interop, implementing parameters and EventCallback, RenderFragment slots, component lifecycle (OnInitializedAsync, OnParametersSet), async patterns, IAsyncDisposable, CancellationToken, CSS isolation, code-behind. DO NOT USE FOR: creating new projects (use create-blazor-project), JavaScript interop or calling browser APIs from Blazor (use use-js-interop), forms and validation (use collect-user-input), prerendering issues (use support-prerendering), HTTP data fetching patterns (use fetch-and-send-data), coordinating state between unrelated components (use coordinate-components).\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2983,2984,2987,2989,2992],{"name":17,"slug":18,"type":15},{"name":2985,"slug":2986,"type":15},"Blazor","blazor",{"name":2988,"slug":1142,"type":15},"C#",{"name":2990,"slug":2991,"type":15},"UI Components","ui-components",{"name":2993,"slug":2994,"type":15},"Web Development","web-development","2026-07-15T06:03:29.216359",{"slug":2997,"name":2997,"fn":2998,"description":2999,"org":3000,"tags":3001,"stars":25,"repoUrl":26,"updatedAt":3005},"binlog-failure-analysis","analyze MSBuild binary logs","Analyze MSBuild binary logs to diagnose build failures. USE FOR: build errors that are unclear from console output, diagnosing cascading failures across multi-project builds, tracing MSBuild target execution order, and generally any MSBuild build issues. Requires an existing .binlog file. DO NOT USE FOR: generating binlogs (use binlog-generation), non-MSBuild build systems.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3002,3003,3004],{"name":2925,"slug":2926,"type":15},{"name":2928,"slug":2929,"type":15},{"name":2943,"slug":2944,"type":15},"2026-07-12T08:21:34.637923",{"slug":3007,"name":3007,"fn":3008,"description":3009,"org":3010,"tags":3011,"stars":25,"repoUrl":26,"updatedAt":3017},"binlog-generation","generate MSBuild binary logs for diagnostics","Generate MSBuild binary logs (binlogs) for build diagnostics and analysis. USE FOR: adding \u002Fbl:{} to any dotnet build, test, pack, publish, or restore command to capture a full build execution trace, prerequisite for binlog-failure-analysis and build-perf-diagnostics skills, enabling post-build investigation of errors or performance. Requires MSBuild 17.8+ \u002F .NET 8 SDK+ for {} placeholder; PowerShell needs -bl:{{}}. DO NOT USE FOR: non-MSBuild build systems (npm, Maven, CMake), analyzing an existing binlog (use binlog-failure-analysis instead).",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3012,3015,3016],{"name":3013,"slug":3014,"type":15},"Build","build",{"name":2928,"slug":2929,"type":15},{"name":2909,"slug":2910,"type":15},"2026-07-19T05:38:19.340791",{"slug":3019,"name":3019,"fn":3020,"description":3021,"org":3022,"tags":3023,"stars":25,"repoUrl":26,"updatedAt":3027},"build-parallelism","optimize MSBuild build parallelism","Diagnose and fix under-parallelized MSBuild builds. USE WHEN a multi-project solution build is slower than expected, doesn't speed up when you add cores, pegs a single core while others idle, or you want to know why `-m` isn't helping. Note: `\u002Fmaxcpucount` default is 1 (sequential) — always pass `-m` for parallel builds. Covers finding the critical path (longest serial ProjectReference chain), graph build (`\u002Fgraph`), BuildInParallel, and solution filters (`.slnf`). DO NOT USE FOR: single-project builds, incremental issues (use incremental-build), compilation slowness inside one project (use build-perf-diagnostics), non-MSBuild build systems.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3024,3025,3026],{"name":17,"slug":18,"type":15},{"name":2909,"slug":2910,"type":15},{"name":2912,"slug":2913,"type":15},"2026-07-19T05:38:18.364937",{"slug":3029,"name":3029,"fn":3030,"description":3031,"org":3032,"tags":3033,"stars":25,"repoUrl":26,"updatedAt":3040},"build-perf-baseline","establish and optimize build performance baselines","Establish build performance baselines and apply systematic optimization techniques. USE FOR: diagnosing slow builds, establishing before\u002Fafter measurements (cold, warm, no-op scenarios), applying optimization strategies like MSBuild Server, static graph builds, artifacts output, and dependency graph trimming. Start here before diving into build-perf-diagnostics, incremental-build, or build-parallelism. DO NOT USE FOR: non-MSBuild build systems, detailed bottleneck analysis (use build-perf-diagnostics after baselining).",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3034,3035,3038,3039],{"name":2909,"slug":2910,"type":15},{"name":3036,"slug":3037,"type":15},"Monitoring","monitoring",{"name":2912,"slug":2913,"type":15},{"name":2974,"slug":2975,"type":15},"2026-07-12T08:21:35.865649",{"slug":3042,"name":3042,"fn":3043,"description":3044,"org":3045,"tags":3046,"stars":25,"repoUrl":26,"updatedAt":3051},"build-perf-diagnostics","diagnose MSBuild build performance bottlenecks","Diagnose MSBuild build performance bottlenecks using binary log analysis. USE FOR: identifying why builds are slow by analyzing binlog performance summaries, detecting ResolveAssemblyReference (RAR) taking >5s, Roslyn analyzers consuming >30% of Csc time, single targets dominating >50% of build time, node utilization below 80%, excessive Copy tasks, NuGet restore running every build. Covers timeline analysis, Target\u002FTask Performance Summary interpretation, and 7 common bottleneck categories. Use after build-perf-baseline has established measurements. DO NOT USE FOR: establishing initial baselines (use build-perf-baseline first), fixing incremental build issues (use incremental-build), parallelism tuning (use build-parallelism), non-MSBuild build systems.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3047,3048,3049,3050],{"name":17,"slug":18,"type":15},{"name":2928,"slug":2929,"type":15},{"name":2909,"slug":2910,"type":15},{"name":2912,"slug":2913,"type":15},"2026-07-12T08:21:40.961722",{"slug":3053,"name":3053,"fn":3054,"description":3055,"org":3056,"tags":3057,"stars":25,"repoUrl":26,"updatedAt":3061},"check-bin-obj-clash","detect MSBuild output path conflicts","Detects MSBuild projects with conflicting OutputPath or IntermediateOutputPath. USE FOR: builds failing with 'Cannot create a file when that file already exists', 'The process cannot access the file because it is being used by another process', intermittent build failures that succeed on retry, or missing\u002Foverwritten outputs in multi-project or multi-targeting builds where bin\u002Fobj (or project.assets.json) collide. Common causes: shared OutputPath, missing AppendTargetFrameworkToOutputPath, extra global properties (e.g. PublishReadyToRun), or SetTargetFramework on a ProjectReference to a single-targeting project. DO NOT USE FOR: file access errors unrelated to MSBuild (OS-level locking), single-project single-TFM builds, non-MSBuild build systems.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3058,3059,3060],{"name":2928,"slug":2929,"type":15},{"name":2909,"slug":2910,"type":15},{"name":2971,"slug":2972,"type":15},"2026-07-19T05:38:14.336279",144,{"items":3064,"total":3113},[3065,3072,3079,3087,3093,3101,3107],{"slug":2918,"name":2918,"fn":2919,"description":2920,"org":3066,"tags":3067,"stars":25,"repoUrl":26,"updatedAt":2931},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3068,3069,3070,3071],{"name":17,"slug":18,"type":15},{"name":2925,"slug":2926,"type":15},{"name":2928,"slug":2929,"type":15},{"name":2912,"slug":2913,"type":15},{"slug":2933,"name":2933,"fn":2934,"description":2935,"org":3073,"tags":3074,"stars":25,"repoUrl":26,"updatedAt":2945},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3075,3076,3077,3078],{"name":17,"slug":18,"type":15},{"name":2681,"slug":2940,"type":15},{"name":2928,"slug":2929,"type":15},{"name":2943,"slug":2944,"type":15},{"slug":2947,"name":2947,"fn":2948,"description":2949,"org":3080,"tags":3081,"stars":25,"repoUrl":26,"updatedAt":2962},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3082,3083,3084,3085,3086],{"name":17,"slug":18,"type":15},{"name":2928,"slug":2929,"type":15},{"name":2668,"slug":2955,"type":15},{"name":2957,"slug":2958,"type":15},{"name":2960,"slug":2961,"type":15},{"slug":2964,"name":2964,"fn":2965,"description":2966,"org":3088,"tags":3089,"stars":25,"repoUrl":26,"updatedAt":2976},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3090,3091,3092],{"name":2925,"slug":2926,"type":15},{"name":2971,"slug":2972,"type":15},{"name":2974,"slug":2975,"type":15},{"slug":2978,"name":2978,"fn":2979,"description":2980,"org":3094,"tags":3095,"stars":25,"repoUrl":26,"updatedAt":2995},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3096,3097,3098,3099,3100],{"name":17,"slug":18,"type":15},{"name":2985,"slug":2986,"type":15},{"name":2988,"slug":1142,"type":15},{"name":2990,"slug":2991,"type":15},{"name":2993,"slug":2994,"type":15},{"slug":2997,"name":2997,"fn":2998,"description":2999,"org":3102,"tags":3103,"stars":25,"repoUrl":26,"updatedAt":3005},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3104,3105,3106],{"name":2925,"slug":2926,"type":15},{"name":2928,"slug":2929,"type":15},{"name":2943,"slug":2944,"type":15},{"slug":3007,"name":3007,"fn":3008,"description":3009,"org":3108,"tags":3109,"stars":25,"repoUrl":26,"updatedAt":3017},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3110,3111,3112],{"name":3013,"slug":3014,"type":15},{"name":2928,"slug":2929,"type":15},{"name":2909,"slug":2910,"type":15},96]