From 0686c754de94b6405360ca91ff1dced587403253 Mon Sep 17 00:00:00 2001 From: David Britch Date: Mon, 23 Oct 2023 14:22:46 +0100 Subject: [PATCH] Single use query parameters for GoToAsync (#1815) * Single use query parameters. * Edit. * Edits. --- docs/fundamentals/shell/navigation.md | 42 +++++++++++++++++++++++++-- docs/whats-new/dotnet-8.md | 1 + 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/docs/fundamentals/shell/navigation.md b/docs/fundamentals/shell/navigation.md index 0593d46e5..94e8a7565 100644 --- a/docs/fundamentals/shell/navigation.md +++ b/docs/fundamentals/shell/navigation.md @@ -1,7 +1,7 @@ --- title: ".NET MAUI Shell navigation" description: "Learn how .NET MAUI Shell apps can utilize a URI-based navigation experience that permits navigation to any page in the app, without having to follow a set navigation hierarchy." -ms.date: 04/07/2022 +ms.date: 10/23/2023 --- # .NET MAUI Shell navigation @@ -352,7 +352,7 @@ async void OnCollectionViewSelectionChanged(object sender, SelectionChangedEvent This example retrieves the currently selected elephant in the , and navigates to the `elephantdetails` route, passing `elephantName` as a query parameter. -Object-based navigation data can be passed with a `GoToAsync` overload that specifies an `IDictionary` argument: +Multiple use object-based navigation data can be passed with a `GoToAsync` overload that specifies an `IDictionary` argument: ```csharp async void OnCollectionViewSelectionChanged(object sender, SelectionChangedEventArgs e) @@ -368,6 +368,34 @@ async void OnCollectionViewSelectionChanged(object sender, SelectionChangedEvent This example retrieves the currently selected bear in the , as an `Animal`. The `Animal` object is added to a `Dictionary` with the key `Bear`. Then, navigation to the `beardetails` route is performed, with the `Dictionary` being passed as a navigation parameter. +Any data that's passed as an `IDictionary` argument is retained in memory for the lifetime of the page, and isn't released until the page is removed from the navigation stack. This can be problematic, as shown in the following scenario: + +1. `Page1` navigates to `Page2` using the `GoToAsync` method, passing in an object called `MyData`. `Page2` then receives `MyData` as a query parameter. +1. `Page2` navigates to `Page3` using the `GoToAsync` method, without passing any data. +1. `Page3` navigates backwards with the `GoToAsync` method. `Page2` then receives `MyData` again as a query parameter. + +While this is desirable in many scenarios, if it isn't desired you should clear the `IDictionary` argument with the `Clear` method after it's first been received by a page. + +::: moniker range=">=net-maui-8.0" + +Alternatively, you can use the `GoToAsync` overload that enables you to pass single use navigation data as a `ShellNavigationQueryParameters` object. A `ShellNavigationQueryParameters` object is intended for navigation data that's cleared after navigation has occurred. The following example shows navigating while passing data as a `ShellNavigationQueryParameters` object: + +```csharp +async void OnCollectionViewSelectionChanged(object sender, SelectionChangedEventArgs e) +{ + Animal animal = e.CurrentSelection.FirstOrDefault() as Animal; + var navigationParameter = new ShellNavigationQueryParameters + { + { "Bear", animal } + }; + await Shell.Current.GoToAsync($"beardetails", navigationParameter); +} +``` + +This example retrieves the currently selected bear in the , as an `Animal` that's added to the `ShellNavigationQueryParameters` object. Then, navigation to the `beardetails` route is performed, with the `ShellNavigationQueryParameters` object being passed as a navigation parameter. After navigation has occurred the data in the `ShellNavigationQueryParameters` object is cleared. + +::: moniker-end + There are two approaches to receiving navigation data: 1. The class that represents the page being navigated to, or the class for the page's `BindingContext`, can be decorated with a `QueryPropertyAttribute` for each query parameter. For more information, see [Process navigation data using query property attributes](#process-navigation-data-using-query-property-attributes). @@ -375,8 +403,18 @@ There are two approaches to receiving navigation data: ### Process navigation data using query property attributes +::: moniker range="=net-maui-7.0" + Navigation data can be received by decorating the receiving class with a `QueryPropertyAttribute` for each string-based query parameter and object-based navigation parameter: +::: moniker-end + +::: moniker range=">=net-maui-8.0" + +Navigation data can be received by decorating the receiving class with a `QueryPropertyAttribute` for each string-based query parameter, object-based navigation parameter, or `ShellNavigationQueryParameters` object: + +::: moniker-end + ```csharp [QueryProperty(nameof(Bear), "Bear")] public partial class BearDetailPage : ContentPage diff --git a/docs/whats-new/dotnet-8.md b/docs/whats-new/dotnet-8.md index 8ed6bca04..a71cb0d34 100644 --- a/docs/whats-new/dotnet-8.md +++ b/docs/whats-new/dotnet-8.md @@ -39,6 +39,7 @@ For information about what's new in .NET 8, see [What's new in .NET 8](/dotnet/c - The class gains the `Bluetooth` permission, which is an Android 12 permission for looking for Bluetooth devices, making the current device discoverable to other Bluetooth devices, and communicating with already-paired Bluetooth devices. For more information, see [Permissions](~/platform-integration/appmodel/permissions.md). - The class gains the `NearbyWifiDevices` permission, which is an Android 13 permission for accessing nearby WiFi devices. For more information, see [Permissions](~/platform-integration/appmodel/permissions.md). - Several system fonts can be easily consumed in Android apps. For more information, see [Consume fonts](~/user-interface/fonts.md#consume-fonts). +- Shell navigation gains a `GoToAsync` overload that enables you to pass single use navigation data, that's cleared after navigation has occurred, as a `ShellNavigationQueryParameters` object. For more information, see [Pass data](~/fundamentals/shell/navigation.md#pass-data). The following types or members have been deprecated: