csharp-scripts
Run file-based C# apps with the .NET CLI when the user explicitly wants C#/.NET code without creating a project. Use for C#…
.NET MAUI app lifecycle guidance — the four app states, cross-platform Window lifecycle events (Created, Activated, Deactivated, Stopped, Resumed, Destroying), platform-specific lifecycle mapping, backgrounding and resume behavior, and state-preservation patterns. USE FOR: "app
Claude Code
$ npx -y skills add dotnet/skills --skill maui-app-lifecycle --agent claude-code
Codex
$ npx skills add dotnet/skills --skill maui-app-lifecycle -a codex -y
Cursor
$ npx skills add dotnet/skills --skill maui-app-lifecycle -a cursor -y
Gemini CLI
$ npx skills add dotnet/skills --skill maui-app-lifecycle -a gemini-cli -y
GitHub Copilot
$ npx skills add dotnet/skills --skill maui-app-lifecycle -a github-copilot -y
OpenCode
$ npx skills add dotnet/skills --skill maui-app-lifecycle -a opencode -y
Windsurf
$ npx skills add dotnet/skills --skill maui-app-lifecycle -a windsurf -y
name: maui-app-lifecycle description: >- .NET MAUI app lifecycle guidance — the four app states, cross-platform Window lifecycle events (Created, Activated, Deactivated, Stopped, Resumed, Destroying), platform-specific lifecycle mapping, backgrounding and resume behavior, and state-preservation patterns. USE FOR: "app lifecycle", "window lifecycle events", "save state on background", "resume app", "OnStopped", "OnResumed", "backgrounding", "deactivated event", "ConfigureLifecycleEvents", "platform lifecycle hooks". DO NOT USE FOR: navigation events (use maui-shell-navigation), dependency injection setup (use maui-dependency-injection), platform API invocation (use conditional compilation and partial classes). license: MIT
Handle application state transitions correctly in .NET MAUI. This skill covers the cross-platform Window lifecycle events, their platform-native mappings, and patterns for preserving state across backgrounding and resume cycles.
A .NET MAUI app moves through four states:
| State | Description | |---|---| | **Not Running** | Process does not exist | | **Running** | Foreground, receiving input | | **Deactivated** | Visible but lost focus (dialog, split-screen, notification shade) | | **Stopped** | Fully backgrounded, UI not visible |
Typical flow: Not Running → Running → Deactivated → Stopped → Running (resumed) or Not Running (terminated).
`Microsoft.Maui.Controls.Window` exposes six cross-platform events:
| Event | Fires when | |---|---| | `Created` | Native window allocated | | `Activated` | Window receives input focus | | `Deactivated` | Window loses focus (may still be visible) | | `Stopped` | Window is no longer visible | | `Resumed` | Window returns to foreground after Stopped | | `Destroying` | Native window is being torn down |
Override `CreateWindow` in your `App` class and attach event handlers:
public partial class App : Application
{
protected override Window CreateWindow(IActivationState? activationState)
{
var window = base.CreateWindow(activationState);
window.Created += (s, e) => Debug.WriteLine("Created");
window.Activated += (s, e) => Debug.WriteLine("Activated");
window.Deactivated += (s, e) => Debug.WriteLine("Deactivated");
window.Stopped += (s, e) => Debug.WriteLine("Stopped");
window.Resumed += (s, e) => Debug.WriteLine("Resumed");
window.Destroying += (s, e) => Debug.WriteLine("Destroying");
return window;
}
}Create a `Window` subclass and override the virtual methods:
public class AppWindow : Window
{
public AppWindow(Page page) : base(page) { }
protected override void OnActivated() { /* refresh UI */ }
protected override void OnStopped() { /* save state */ }
protected override void OnResumed() { /* restore state */ }
protected override void OnDestroying() { /* cleanup */ }
}Return it from `CreateWindow`:
protected override Window CreateWindow(IActivationState? activationState)
=> new AppWindow(new AppShell());1. **Identify transient state** — draft text, scroll position, form inputs, timer values. 2. **Save in `OnStopped`** — use `Preferences` for small values or file serialization for larger state. 3. **Restore in `OnResumed`** — read back saved values and apply to your view model. 4. **Also save in `OnDestroying`** on Android — the back button can skip `Stopped` entirely. 5. **Keep handlers fast** — complete within 1–2 seconds to avoid ANR on Android or watchdog kills on iOS.
protected override void OnStopped()
{
base.OnStopped();
Preferences.Set("draft_text", _viewModel.DraftText);
Preferences.Set("scroll_y", _viewModel.ScrollY);
}
protected override void OnResumed()
{
base.OnResumed();
_viewModel.DraftText = Preferences.Get("draft_text", string.Empty);
_viewModel.ScrollY = Preferences.Get("scroll_y", 0.0);
}
protected override void OnDestroying()
{
base.OnDestroying();
// Android back-button can skip Stopped
Preferences.Set("draft_text", _viewModel.DraftText);
}| Window Event | Android Callback | |---|---| | Created | `OnCreate` | | Activated | `OnResume` | | Deactivated | `OnPause` | | Stopped | `OnStop` | | Resumed | `OnRestart` → `OnStart` → `OnResume` | | Destroying | `OnDestroy` |
| Window Event | UIKit Callback | `AddiOS` builder method | |---|---|---| | Created | `WillFinishLaunching` / `SceneWillConnect` | `.WillFinishLaunching()` / `.SceneWillConnect()` | | Activated | `DidBecomeActive` | `.OnActivated()` | | Deactivated | `WillResignActive` | `.OnResignActivation()` | | Stopped | `DidEnterBackground` | `.DidEnterBackground()` | | Resumed | `WillEnterForeground` | `.WillEnterForeground()` | | Destroying | `WillT
This repository contains the .NET team's curated set of portable skills and host-specific custom agents for coding agents. For information about the Agent Skills standard, see agentskills.io.
Run file-based C# apps with the .NET CLI when the user explicitly wants C#/.NET code without creating a project. Use for C#…
Correctly call native (C/C++) libraries from .NET using P/Invoke and LibraryImport. Covers function signatures, string…
Set up NuGet trusted publishing (OIDC) on a GitHub Actions repo — replaces long-lived API keys with short-lived tokens. USE FOR:…
Design, implement, optimize, and review SIMD code in .NET. USE FOR: vectorizing scalar loops with TensorPrimitives,…
Guides technology selection and implementation of AI and ML features in .NET 8+ applications using ML.NET,…
Guides conversion of a pre-.NET 8 Blazor Server app into a .NET 8+ Blazor Web App. USE FOR: migrating apps that use…
You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…
Ask which skill or flow fits your situation. A router over the skills in this repo.