From bfed2d519cb2204098e4b3bfc0271d7825554067 Mon Sep 17 00:00:00 2001 From: David Ortinau Date: Thu, 6 Aug 2026 07:20:21 -0500 Subject: [PATCH 1/4] Platform (.NET 11): document Preview 7 APIs Document media capture gallery saves, mobile status bar themes, and Windows single-instance activation. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- docs/fundamentals/app-lifecycle.md | 84 ++++++++++++++++++- .../device-media/picker.md | 16 +++- docs/user-interface/controls/window.md | 32 ++++++- 3 files changed, 129 insertions(+), 3 deletions(-) diff --git a/docs/fundamentals/app-lifecycle.md b/docs/fundamentals/app-lifecycle.md index 9dc632802d..4f74e2742c 100644 --- a/docs/fundamentals/app-lifecycle.md +++ b/docs/fundamentals/app-lifecycle.md @@ -1,7 +1,7 @@ --- title: "App lifecycle" description: ".NET MAUI raises cross-platform lifecycle events when an app transitions between its different execution states." -ms.date: 08/30/2024 +ms.date: 08/06/2026 --- # App lifecycle @@ -378,6 +378,88 @@ namespace PlatformLifecycleDemo } ``` +::: moniker range=">=net-maui-11.0" + +#### Handle AppInstance activation + +On Windows, the `OnAppInstanceActivated` lifecycle hook receives the initial activation and subsequent file, protocol, and redirected activations. Its handler receives an object and returns a `bool` that indicates whether the activation has been handled. + +You can use this hook to make your app single-instanced. Register an app key with , and redirect activations from other instances to the registered instance: + +```csharp +using System.Diagnostics; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.Maui.LifecycleEvents; +using Microsoft.Windows.AppLifecycle; + +namespace PlatformLifecycleDemo; + +public static class MauiProgram +{ + public static MauiApp CreateMauiApp() + { + var builder = MauiApp.CreateBuilder(); + builder + .UseMauiApp() + .ConfigureLifecycleEvents(events => + { +#if WINDOWS + events.AddWindows(windows => windows + .OnAppInstanceActivated(HandleAppInstanceActivated)); +#endif + }); + + return builder.Build(); + } + +#if WINDOWS + static bool HandleAppInstanceActivated( + Microsoft.UI.Xaml.Application application, + AppActivationArguments args) + { + AppInstance keyInstance = + AppInstance.FindOrRegisterForKey("PlatformLifecycleDemo"); + + if (!keyInstance.IsCurrent) + { + _ = RedirectActivationAndExitAsync(keyInstance, args); + return true; + } + + if (Application.Current?.Windows.FirstOrDefault() is Window window) + { + Application.Current.ActivateWindow(window); + } + + return false; + } + + static async Task RedirectActivationAndExitAsync( + AppInstance keyInstance, + AppActivationArguments args) + { + try + { + await keyInstance.RedirectActivationToAsync(args) + .AsTask() + .ConfigureAwait(false); + } + finally + { + Process.GetCurrentProcess().Kill(); + } + } +#endif +} +``` + +Returning `true` from the transient instance marks the activation as handled and prevents it from creating a window. Always await before terminating that process so that the running instance can consume the activation. + +.NET MAUI uses this activation lifecycle to support callbacks on Windows. If your app registers its own `AppInstance` key, it owns activation routing and must redirect every external activation, including protocol activations, to the instance that started the authentication operation. + +::: moniker-end + ### Retrieve the Window object Platform code can retrieve the app's `Window` object from platform lifecycle events, with the `GetWindow` extension method: diff --git a/docs/platform-integration/device-media/picker.md b/docs/platform-integration/device-media/picker.md index 5ab4b00a82..37e5f0a043 100644 --- a/docs/platform-integration/device-media/picker.md +++ b/docs/platform-integration/device-media/picker.md @@ -1,7 +1,7 @@ --- title: "Media picker for photos and videos" description: "Learn how to use the IMediaPicker interface in the Microsoft.Maui.Media namespace, to prompt the user to select or take a photo or video" -ms.date: 07/08/2026 +ms.date: 08/06/2026 no-loc: ["Microsoft.Maui", "Microsoft.Maui.Media", "MediaPicker"] --- @@ -192,6 +192,20 @@ foreach (var file in results) ::: moniker range=">=net-maui-11.0" +### Save captured media to the gallery + +The property controls whether a captured photo or video is also saved to the device's gallery. The default value is `false`, and the property only applies to and operations. It's ignored by media pick operations. + +```csharp +FileResult? photo = await MediaPicker.Default.CapturePhotoAsync( + new MediaPickerOptions + { + SaveToGallery = true + }); +``` + +Saving captured media to the gallery is supported on Android, iOS, and Mac Catalyst. On iOS and Mac Catalyst, the `NSPhotoLibraryAddUsageDescription` key must be present in *Info.plist*. On Android versions earlier than API 29, the `WRITE_EXTERNAL_STORAGE` permission is required. The property is ignored on Windows and Tizen. + ### Recover interrupted Android media picker operations On Android, the system can destroy and recreate your app while the camera or photo picker UI is in front. If the original media picker task is gone when your app resumes, use the Android-only recovery APIs to retrieve any accepted results. diff --git a/docs/user-interface/controls/window.md b/docs/user-interface/controls/window.md index a755c79942..149831bad0 100644 --- a/docs/user-interface/controls/window.md +++ b/docs/user-interface/controls/window.md @@ -1,7 +1,7 @@ --- title: "Window" description: "Learn how to use the .NET MAUI Window class to create, configure, show, and manage multi-window apps." -ms.date: 08/19/2025 +ms.date: 08/06/2026 --- # Window @@ -17,6 +17,9 @@ The .NET Multi-platform App UI (.NET MAUI) - , of type `double`, represents the minimum height of the window on desktop platforms. Valid values are between 0 and `double.PositiveInfinity`. - , of type `double`, represents the minimum width of the window on desktop platforms. Valid values are between 0 and `double.PositiveInfinity`. - , of type `IReadOnlyCollection`, represents the collection of window overlays. +::: moniker range=">=net-maui-11.0" +- , of type , controls the appearance of the status bar icons on Android and iOS. +::: moniker-end - , of type , indicates the page being displayed by the window. This property is the content property of the class, and therefore does not need to be explicitly set. - , of type `string`, represents the title of the window. - , of type `double`, specifies the width of the window on Windows. @@ -51,6 +54,33 @@ The class also defines the following modal The class has a `Window` property that exposes the parent object. This property can be accessed from any page, layout, or view, to manipulate objects. +::: moniker range=">=net-maui-11.0" + +## Set the status bar theme + +On Android and iOS, set to control the appearance of the operating system-drawn status bar icons independently of the app theme. The default value, , follows the current app theme. + +Choose the value that matches the surface behind the status bar: + +- indicates a light surface and displays dark icons. +- indicates a dark surface and displays light icons. + +For example, if the app uses a dark header behind the status bar while the rest of the app uses a light theme, set `StatusBarTheme` to `Dark`: + +```csharp +protected override Window CreateWindow(IActivationState? activationState) +{ + return new Window(new AppShell()) + { + StatusBarTheme = StatusBarTheme.Dark + }; +} +``` + +This property has no effect on Mac Catalyst, Windows, or Tizen. + +::: moniker-end + ## Create a Window ::: moniker range="=net-maui-8.0" From 33781e91a017b8cdbf61209e5e7595fa11a45274 Mon Sep 17 00:00:00 2001 From: David Ortinau Date: Thu, 6 Aug 2026 07:25:47 -0500 Subject: [PATCH 2/4] Window (.NET 11): clarify Android status bar support Document the Android API 23 minimum for Window.StatusBarTheme. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- docs/user-interface/controls/window.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/user-interface/controls/window.md b/docs/user-interface/controls/window.md index 149831bad0..5f6b80ceb7 100644 --- a/docs/user-interface/controls/window.md +++ b/docs/user-interface/controls/window.md @@ -18,7 +18,7 @@ The .NET Multi-platform App UI (.NET MAUI) - , of type `double`, represents the minimum width of the window on desktop platforms. Valid values are between 0 and `double.PositiveInfinity`. - , of type `IReadOnlyCollection`, represents the collection of window overlays. ::: moniker range=">=net-maui-11.0" -- , of type , controls the appearance of the status bar icons on Android and iOS. +- , of type , controls the appearance of the status bar icons on Android 6.0 (API 23) or later and iOS. ::: moniker-end - , of type , indicates the page being displayed by the window. This property is the content property of the class, and therefore does not need to be explicitly set. - , of type `string`, represents the title of the window. @@ -58,7 +58,7 @@ The class has a `Window` property t ## Set the status bar theme -On Android and iOS, set to control the appearance of the operating system-drawn status bar icons independently of the app theme. The default value, , follows the current app theme. +On Android 6.0 (API 23) or later and iOS, set to control the appearance of the operating system-drawn status bar icons independently of the app theme. The default value, , follows the current app theme. Choose the value that matches the surface behind the status bar: @@ -77,7 +77,7 @@ protected override Window CreateWindow(IActivationState? activationState) } ``` -This property has no effect on Mac Catalyst, Windows, or Tizen. +This property has no effect on Android versions earlier than API 23, Mac Catalyst, Windows, or Tizen. ::: moniker-end From 059f723a9688703080e0549575cf6ead3dcb0c4c Mon Sep 17 00:00:00 2001 From: David Ortinau Date: Thu, 6 Aug 2026 07:40:30 -0500 Subject: [PATCH 3/4] Docs (.NET 11): avoid unresolved Preview 7 xrefs Format new Preview 7 API names as code until their reference metadata is available. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- docs/platform-integration/device-media/picker.md | 2 +- docs/user-interface/controls/window.md | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/platform-integration/device-media/picker.md b/docs/platform-integration/device-media/picker.md index 37e5f0a043..a38aeafaf2 100644 --- a/docs/platform-integration/device-media/picker.md +++ b/docs/platform-integration/device-media/picker.md @@ -194,7 +194,7 @@ foreach (var file in results) ### Save captured media to the gallery -The property controls whether a captured photo or video is also saved to the device's gallery. The default value is `false`, and the property only applies to and operations. It's ignored by media pick operations. +The `MediaPickerOptions.SaveToGallery` property controls whether a captured photo or video is also saved to the device's gallery. The default value is `false`, and the property only applies to and operations. It's ignored by media pick operations. ```csharp FileResult? photo = await MediaPicker.Default.CapturePhotoAsync( diff --git a/docs/user-interface/controls/window.md b/docs/user-interface/controls/window.md index 5f6b80ceb7..e101411a5a 100644 --- a/docs/user-interface/controls/window.md +++ b/docs/user-interface/controls/window.md @@ -18,7 +18,7 @@ The .NET Multi-platform App UI (.NET MAUI) - , of type `double`, represents the minimum width of the window on desktop platforms. Valid values are between 0 and `double.PositiveInfinity`. - , of type `IReadOnlyCollection`, represents the collection of window overlays. ::: moniker range=">=net-maui-11.0" -- , of type , controls the appearance of the status bar icons on Android 6.0 (API 23) or later and iOS. +- `Window.StatusBarTheme`, of type `StatusBarTheme`, controls the appearance of the status bar icons on Android 6.0 (API 23) or later and iOS. ::: moniker-end - , of type , indicates the page being displayed by the window. This property is the content property of the class, and therefore does not need to be explicitly set. - , of type `string`, represents the title of the window. @@ -58,12 +58,12 @@ The class has a `Window` property t ## Set the status bar theme -On Android 6.0 (API 23) or later and iOS, set to control the appearance of the operating system-drawn status bar icons independently of the app theme. The default value, , follows the current app theme. +On Android 6.0 (API 23) or later and iOS, set `Window.StatusBarTheme` to control the appearance of the operating system-drawn status bar icons independently of the app theme. The default value, `StatusBarTheme.Default`, follows the current app theme. Choose the value that matches the surface behind the status bar: -- indicates a light surface and displays dark icons. -- indicates a dark surface and displays light icons. +- `StatusBarTheme.Light` indicates a light surface and displays dark icons. +- `StatusBarTheme.Dark` indicates a dark surface and displays light icons. For example, if the app uses a dark header behind the status bar while the rest of the app uses a light theme, set `StatusBarTheme` to `Dark`: From 9415d5ae3e705e4335799532b51abd8be932e1c3 Mon Sep 17 00:00:00 2001 From: David Ortinau Date: Tue, 11 Aug 2026 08:24:56 -0500 Subject: [PATCH 4/4] App lifecycle (.NET 11): address activation review Use standard single-instance terminology and shut down the transient WinUI app normally after activation redirection completes. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- docs/fundamentals/app-lifecycle.md | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/docs/fundamentals/app-lifecycle.md b/docs/fundamentals/app-lifecycle.md index 4f74e2742c..a2f661ce5c 100644 --- a/docs/fundamentals/app-lifecycle.md +++ b/docs/fundamentals/app-lifecycle.md @@ -1,7 +1,7 @@ --- title: "App lifecycle" description: ".NET MAUI raises cross-platform lifecycle events when an app transitions between its different execution states." -ms.date: 08/06/2026 +ms.date: 08/11/2026 --- # App lifecycle @@ -384,10 +384,9 @@ namespace PlatformLifecycleDemo On Windows, the `OnAppInstanceActivated` lifecycle hook receives the initial activation and subsequent file, protocol, and redirected activations. Its handler receives an object and returns a `bool` that indicates whether the activation has been handled. -You can use this hook to make your app single-instanced. Register an app key with , and redirect activations from other instances to the registered instance: +You can use this hook to implement a single-instance app. Register an app key with , and redirect activations from other instances to the registered instance: ```csharp -using System.Diagnostics; using System.Linq; using System.Threading.Tasks; using Microsoft.Maui.LifecycleEvents; @@ -423,7 +422,7 @@ public static class MauiProgram if (!keyInstance.IsCurrent) { - _ = RedirectActivationAndExitAsync(keyInstance, args); + _ = RedirectActivationAndExitAsync(application, keyInstance, args); return true; } @@ -436,25 +435,24 @@ public static class MauiProgram } static async Task RedirectActivationAndExitAsync( + Microsoft.UI.Xaml.Application application, AppInstance keyInstance, AppActivationArguments args) { try { - await keyInstance.RedirectActivationToAsync(args) - .AsTask() - .ConfigureAwait(false); + await keyInstance.RedirectActivationToAsync(args).AsTask(); } finally { - Process.GetCurrentProcess().Kill(); + application.Exit(); } } #endif } ``` -Returning `true` from the transient instance marks the activation as handled and prevents it from creating a window. Always await before terminating that process so that the running instance can consume the activation. +Returning `true` from the transient instance marks the activation as handled and prevents it from creating a window. Always await before exiting that app instance so that the running instance can consume the activation. .NET MAUI uses this activation lifecycle to support callbacks on Windows. If your app registers its own `AppInstance` key, it owns activation routing and must redirect every external activation, including protocol activations, to the instance that started the authentication operation.