diff --git a/doc/Reference/Navigation/Design.md b/doc/Reference/Navigation/Design.md
index 567e2b72bc..b6b9ad2509 100644
--- a/doc/Reference/Navigation/Design.md
+++ b/doc/Reference/Navigation/Design.md
@@ -19,43 +19,22 @@ There are `INavigator` extension methods that accept a variety of parameters, de
## Navigation Controls
-An application typically has one or more views responsible for controlling navigation. Eg a Frame that navigates between pages, or a TabBar that switches tabs
+An application typically has one or more views responsible for controlling navigation. For example, a Frame that navigates between pages, or a TabBar that switches tabs
-Navigation controls can be categorized in three distinct groups with different Navigation goals.
+Navigation controls can be categorized into three distinct groups with different Navigation goals.
| Content-Based | Has a content area that's used to display the current view |
|----------------------|------------------------------------------------------------------------------------------------------------------------|
| ContentControl | Navigation creates an instance of a control and sets it as the Content |
-| Panel (eg Grid) | Navigation sets a child element to Visible, hiding any previously visible child. Two scenarios:
- An existing child is found. The child is set to Visible
- No child is found. A new instance of a control is created and added to the Panel. The new instance is set to visible
Note that when items are hidden, they're no removed from the visual tree |
-| Frame | Forward navigation adds a new page to the stack based
Backward navigation pops the current page off the stack
Combination eg forward navigation and clear back stack |
+| Panel (eg Grid) | Navigation sets a child element to Visible, hiding any previously visible child. Two scenarios:
- An existing child is found. The child is set to Visible
- No child is found. A new instance of a control is created and added to the Panel. The new instance is set to visible
Note that when items are hidden, they're not removed from the visual tree |
+| Frame | Forward navigation adds a new page to the stack-based
Backward navigation pops the current page off the stack
Combination, for example, forward navigation and clear back stack |
| | |
-| **Selection-Based** | **Has selectable items** |
-| NavigationView | Navigation selects the NavigationViewitem with the correct Region.Name set |
+| **Selection-Based** | **Has selectable items** |
+| NavigationView | Navigation selects the NavigationViewItem with the correct Region.Name set |
| TabBar | Navigation selects the TabBarItem with the correct Region.Name set |
| | |
-| **Prompt-Based (Modal)** | **Modal style prompt, typically for capturing input from user** |
+| **Prompt-Based (Modal)** | **Modal style prompt, typically for capturing input from user** |
| ContentDialog | Forward navigation opens a content dialog
Backward navigation closes the dialog |
| MessageDialog | Forward navigation opens a MessageDialog
Backward navigation closes the MessageDialog |
| Popup | Forward navigation opens the popup
Backward navigation closes the popup |
| Flyout | Forward navigation opens the flyout
Backward navigation closes the flyout |
-
-## Regions
-
-A region is the abstraction of the view responsible for handling navigation.
-
-Regions are structured into a logical hierarchical representation that shadows the navigation-aware controls in the visual hierarchy. The hierarchy allows navigation requests to be propagated up to parent and down to child regions as required.
-
-Regions are specified by setting Region.Attached="true" on a navigation control (eg Frame, ContentControl, Grid).
-
-```csharp
-
-```
-
-Pushing a view to this region:
- `navigator.NavigateRouteAsync(this,"ProductDetails");`
-or
- `navigator.NavigateViewAsync(this);`
-or
- `navigator.NavigateViewModelAsync
+```
+
## Region Name
-Regions can be named by specifying the Region.Name="XXX" property.
+You can name a region by setting the `Region.Name="RegionName"` property.
-For selection-based regions, the selectable items (NavigationViewItem, TabBarItem, …) are identified using the Region.Name property
+In selection-based regions, the selectable items (like `NavigationViewItem`, `TabBarItem`, etc.) are identified using the Region.Name property.
-```csharp
+```xml
@@ -20,6 +33,25 @@ For selection-based regions, the selectable items (NavigationViewItem, TabBarIte
```
Switching selected item:
- `naviator.NavigateRouteAsync(this,"Deals");`
-- Define what a navigation region is and how the hierarchy of regions is created with the Region.Attached property
+ ```csharp
+ navigator.NavigateRouteAsync(this, "Deals");
+ ```
+
+ or
+
+ ```csharp
+ navigator.NavigateViewAsync(this);
+ ```
+
+ or
+
+ ```csharp
+ navigator.NavigateViewModelAsync(this);
+ ```
+
+ or
+
+ ```csharp
+ navigator.NavigateDataAsync(this, selectedDeal);
+ ```
diff --git a/doc/Reference/Navigation/NavigationRequestHandler.md b/doc/Reference/Navigation/NavigationRequestHandler.md
index 2c528b2135..a1a5ffd84c 100644
--- a/doc/Reference/Navigation/NavigationRequestHandler.md
+++ b/doc/Reference/Navigation/NavigationRequestHandler.md
@@ -1,6 +1,87 @@
---
uid: Reference.Navigation.RequestHandler
---
-# Building a Custom Request Handler
-- Show how to create a custom NavigationRequestHandler that will intercept event on a control in order to trigger navigation.
+# Building a Custom Request Handler with `IRequestHandler`
+
+`IRequestHandler` plays a vital role in linking UI controls to navigation requests. This interface allows you to define how a view should respond to a navigation action and helps in handling the routing or navigation logic within a control.
+
+This guide will explain how to create a custom `IRequestHandler` for your own controls, providing examples and best practices to ensure correct implementation.
+
+## What is `IRequestHandler`?
+
+The `IRequestHandler` interface defines two essential methods:
+
+- **`CanBind(FrameworkElement view)`**: This method determines whether the handler can be bound to the given view.
+- **`Bind(FrameworkElement view)`**: This method binds the handler to the view, attaching any necessary logic or event listeners.
+
+```csharp
+public interface IRequestHandler
+{
+ bool CanBind(FrameworkElement view);
+ IRequestBinding? Bind(FrameworkElement view);
+}
+```
+
+These methods allow you to specify how the handler interacts with the control and how it should respond to navigation requests.
+
+## Steps to Create a Custom `IRequestHandler`
+
+### 1. Implement `IRequestHandler`
+
+Start by creating a class that implements the `IRequestHandler` interface. The key part here is to define the specific logic for the control that you want to bind.
+
+Alternatively you could extend one of the provided base classes, depending on your needs:
+
+- `ControlRequestHandlerBase`
+ This base class is useful when you are binding to a specific control type. It already implements `IRequestHandler` and simplifies the process by letting you focus on control-specific logic.
+
+ ```csharp
+ public abstract record ControlRequestHandlerBase(ILogger Logger) : IRequestHandler;
+ ```
+
+- `ActionRequestHandlerBase`
+ If your control needs to handle callback actions when subscribing and unsubscribing to events (such as click events), you should extend `ActionRequestHandlerBase`. This base class adds the necessary infrastructure for subscribing/unsubscribing from control-specific events.
+
+ ```csharp
+ public abstract record ActionRequestHandlerBase(ILogger Logger, IRouteResolver Resolver) : ControlRequestHandlerBase(Logger)
+ where TView : FrameworkElement;
+ ```
+
+### 2. Check if the Control Can Be Bound (`CanBind`)
+
+> [!NOTE]
+> If you are extending `ControlRequestHandlerBase` or `ActionRequestHandlerBase` the `CanBind` method is already implemented. You can check its implementation [here](https://github.com/unoplatform/uno.extensions/blob/d4fa6e44326bf140d08fb1eb205d4acba1ffe202/src/Uno.Extensions.Navigation.UI/Controls/ControlRequestHandlerBase.cs#L14-L37).
+
+In the `CanBind` method, verify that the control you are working with is the correct type. For instance, if you are creating a handler for a custom control named `MyCustomControl`, the `CanBind` method should return `true` only if the `FrameworkElement` is of that type.
+
+Example:
+
+```csharp
+public bool CanBind(FrameworkElement view)
+{
+ return view is MyCustomControl;
+}
+```
+
+This method ensures that your handler will only attempt to bind to appropriate controls.
+
+### 3. Bind the Control to Navigation (`Bind`)
+
+The `Bind` method is where the actual magic happens. Here, you attach event handlers or other logic to respond to the control's events, such as clicks, pointer interactions, or selection changes.
+
+### 4. Manage Resource Cleanup and Unbinding
+
+Ensure that the events are detached properly when the control is unloaded to avoid memory leaks. Your custom `IRequestBinding` should take care of unsubscribing from events when no longer needed.
+
+In the `Bind` method, you should return a `RequestBinding` object that takes care of attaching and detaching event handlers as the control is loaded and unloaded.
+
+### 5. Register Your Custom `IRequestHandler`
+
+After implementing the `IRequestHandler`, you need to register it in your application. Typically, this is done in your service registration:
+
+```csharp
+services.AddSingleton();
+```
+
+This allows your custom handler to be automatically picked up and used whenever a navigation request involves `MyCustomControl`.
diff --git a/doc/Reference/Navigation/Navigator.md b/doc/Reference/Navigation/Navigator.md
index 5a6c42a739..46050adc42 100644
--- a/doc/Reference/Navigation/Navigator.md
+++ b/doc/Reference/Navigation/Navigator.md
@@ -1,9 +1,10 @@
---
uid: Reference.Navigation.Navigator
---
-# Custom INavigator Implementation
-## INavigator
+# INavigator
+
+The `INavigator` is an interface that handles navigating between different views or pages in an application. It manages how you move from one part of your app to another, often keeping track of routes and handling navigation-related tasks.
The `NavigateAsync` method on the `INavigator` interface accepts a NavigationRequest parameter and returns a Task that can be awaited in order to get a NavigationResponse.
@@ -14,6 +15,118 @@ public interface INavigator
}
```
+The `CanNavigate` method checks if the app can navigate to a specific route. It takes a `Route` parameter and returns a `Task`, which tells you whether navigation is possible. Before navigating, you can use CanNavigate to see if it's allowed or makes sense.
+
+```csharp
+public interface INavigator
+{
+ Task CanNavigate(Route route);
+}
+```
+
+## `INavigator` Extension Methods
+
There are `INavigator` extension methods that accept a variety of parameters, depending on the intent, which are mapped to a corresponding combination of Route and Result values.
-- Walk through a simple INavigator implementation
+### Navigates to the specified route
+
+Navigates to the view associated with the route as defined in the `RouteMap`.
+
+```csharp
+Task NavigateRouteAsync(this INavigator navigator, object sender, string route, string qualifier = Qualifiers.None, object? data = null, CancellationToken cancellation = default)
+```
+
+Usage:
+
+```csharp
+var navigationResponse = await _navigator.NavigateRouteAsync(this, route: "MyExample");
+```
+
+### Navigates to the specified view
+
+Navigates to the specified view.
+
+```csharp
+Task NavigateViewAsync(this INavigator navigator, object sender, string qualifier = Qualifiers.None, object? data = null, CancellationToken cancellation = default)
+```
+
+Usage:
+
+```csharp
+var response = await _navigator.NavigateViewAsync(this);
+```
+
+### Navigates to the view through the viewmodel
+
+Navigates to the view associated with the viewmodel as defined in the `ViewMap`.
+
+```csharp
+Task NavigateViewModelAsync(this INavigator navigator, object sender, string qualifier = Qualifiers.None, object? data = null, CancellationToken cancellation = default)
+```
+
+Usage:
+
+```csharp
+var response = await _navigator.NavigateViewModelAsync(this);
+```
+
+### Navigates to the view associated with the data type
+
+Navigates to the view associated with the data type as defined in the `DataViewMap`. The type of the data object will be used to resolve which route to navigate to.
+
+```csharp
+Task NavigateDataAsync(this INavigator navigator, object sender, TData data, string qualifier = Qualifiers.None, CancellationToken cancellation = default)
+```
+
+Usage:
+
+```csharp
+await _navigator.NavigateDataAsync(this);
+```
+
+### Navigates to a Route and Retrieving Result Data
+
+Navigates to a route and get the result of the specified data type, as defined in the `ResultDataViewMap`.
+
+```csharp
+Task?> NavigateForResultAsync(this INavigator navigator, object sender, string qualifier = Qualifiers.None, object? data = null, CancellationToken cancellation = default)
+```
+
+Usage:
+
+```csharp
+var returnObject = await _navigator.NavigateForResultAsync(this);
+```
+
+Alternatively the `GetDataAsync()` could be used:
+
+```csharp
+var returnObject = await _navigator.GetDataAsync(this);
+```
+
+All methods mentioned also have `ForResultAsync` variations available. These variations can be used if you need to retrieve data while navigating. For example:
+
+```csharp
+NavigateRouteForResultAsync()
+NavigateViewForResultAsync()
+NavigateViewModelForResultAsync()
+NavigateDataForResultAsync()
+```
+
+## NavigationResponse
+
+The `NavigationResponse` object encapsulates the result of a navigation operation. It includes:
+
+- **Route**: The route that was navigated to.
+- **Success**: Indicates whether the navigation was successful.
+- **Navigator**: The `INavigator` instance that processed the final segment of the route.
+
+## NavigationRequest
+
+The `NavigationRequest` object represents a request for navigation. It includes:
+
+- **Sender**: The originator of the navigation request.
+- **Route**: The route to navigate to.
+- **Cancellation**: An optional `CancellationToken` to cancel the navigation.
+- **Result**: An optional type for the result of the navigation.
+- **Source**: An optional `INavigator` instance that initiated the navigation.
diff --git a/doc/Reference/Navigation/Qualifiers.md b/doc/Reference/Navigation/Qualifiers.md
index 38ee0614ef..2f5a46d079 100644
--- a/doc/Reference/Navigation/Qualifiers.md
+++ b/doc/Reference/Navigation/Qualifiers.md
@@ -4,10 +4,15 @@ uid: Reference.Navigation.Qualifiers
# Navigation Qualifiers
-| Qualifier | | Example | |
-|-----------|--------------------------------------------------------------|------------------|--------------------------------------------------------------|
-| "" | Navigate to page in frame, or open popup | "Home" | Navigate to the HomePage |
-| / | Forward request to the root region | "/"
"/Login" | Navigate to the default route at the root of navigation
Navigate to LoginPage at the root of navigation |
-| ./ | Forward request to child region | "./Info/Profile" | Navigates to the Profile view in the child region named Info |
-| ! | Open a dialog or flyout | "!Cart" | Shows the Cart flyout |
-| - | Back (Frame), Close (Dialog/Flyout) or respond to navigation | "-"
"--Profile"
"-/Login" | Navigate back one page (in a frame)
Navigate to Profile page and remove two pages from backstack
Navigate to Login page and clear backstack |
+Navigation qualifiers can be utilized to make navigating easier and smoother:
+
+| Qualifier | Description | Example | Example Usage |
+|-----------|-------------------------------------------------|---------------------|--------------------------------------------------------------|
+| "" | Navigate to page in frame or open popup | "Home" | Navigate to the `HomePage` |
+| / | Forward request to the root region | "/"
"/Login" | Navigate to the default route at the root of navigation
Navigate to `LoginPage` at the root of navigation |
+| ./ | Forward request to child region | "./Info/Profile" | Navigate to the Profile view in the child region named Info |
+| ! | Open a dialog or flyout | "!Cart" | Shows the Cart flyout |
+| - | Back (Frame), Close (Dialog/Flyout), or respond to navigation | "-"
"--Profile"
"-/Login" | Navigate back one page (in a frame)
Navigate to `ProfilePage` and remove two pages from back stack
Navigate to `LoginPage` and clear back stack |
+
+> [!NOTE]
+> Besides using qualifiers as a string as part of the route specification, a `Qualifiers` class is also provided under the `Uno.Extensions.Navigation` namespace and can be specified when navigating, for example, `await navigator.NavigateViewModelAsync(this, Qualifiers.ClearBackStack);`.
diff --git a/doc/Reference/Navigation/RouteMap.md b/doc/Reference/Navigation/RouteMap.md
deleted file mode 100644
index c5f5b38821..0000000000
--- a/doc/Reference/Navigation/RouteMap.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-uid: Reference.Navigation.RouteMap
----
-# What is a RouteMap
-
-## RouteMap
-
-In order for navigation to support both view and viewmodel based navigation it is necessary to have some way to define a mapping, or association, between a view and viewmodel (for example MainPage is mapped to MainViewModel, and vice versa). However, given the different intents and behaviors we needed to support, navigation supports a more complex mapping that is referred to as a RouteMap.
-
-A RouteMap is made up of the following components:
-
-| Component | Description |
-|------------|----------------------------------------------------------------------------------------------------------------------------------|
-| Path | The name of the route. When processing a NavigationRequest the Base is used to look up the RouteMap with the corresponding Path.
This is used to match to the Region.Name attribute for PanelVisibilityNavigator, NavigationViewNavigator and TabBarNavigator
NavigateRouteAsync(sender, Path) to navigate to the RouteMap with matching Path.
That Path is also used to populate the deep link at any point in the application. |
-| View | The type of view to be created (or in the case of Frame, navigated to)
NavigateViewAsync(sender) to navigate to the RouteMap with the matching View (type) |
-| ViewModel | The type of view model to be created, and set as DataContext for the current view of the region
NavigateViewModelAsync(sender) to navigate to the RouteMap with the matching ViewModel (type) |
-| Data | The type of data being sent in the navigation request
NavigateDataAsync(sender, Data: data) to navigate to the RouteMap with matching Data (type) |
-| ResultData | The type of data to be returned in the response to the navigation request
NavigateForResultAsync(sender) to navigate to the RouteMap with matching ResultData(type) |
-| IsDefault | Determines which child route should, if any, be used as the default route |
-| Init | Callback function to be invoked prior to navigation for a particular route |
-| ToQuery | Callback function to convert a data object into query parameters (eg Product -> [{"ProductId", "1234"}] ) |
-| FromQuery | Callback function to convert query parameters into a data object (eg [{"ProductId", "1234"}] -> Product ) |
-| Nested | Child routes - currently only used to specify default views for nested regions |
-
-- Explain what a RouteMap is and how it's used to define the route hierarchy in the app
diff --git a/doc/Reference/Navigation/ViewMap.md b/doc/Reference/Navigation/ViewMap.md
deleted file mode 100644
index 3f11945518..0000000000
--- a/doc/Reference/Navigation/ViewMap.md
+++ /dev/null
@@ -1,6 +0,0 @@
----
-uid: Reference.Navigation.ViewMap
----
-# What is a ViewMap
-
-- Define what a viewmap is and the relationship between view, viewmodel and datamap
diff --git a/doc/toc.yml b/doc/toc.yml
index b5d65f0bfc..3e8b32382d 100644
--- a/doc/toc.yml
+++ b/doc/toc.yml
@@ -72,20 +72,16 @@
href: Reference/Reactive/Architecture.md
- name: Analysis rules
href: Reference/Reactive/rules.md
- # - name: Navigation
- # href: Reference/Navigation/Navigation.md
- # items:
- # - name: Design
- # href: Reference/Navigation/Design.md
- # - name: Navigation Region
- # href: Reference/Navigation/NavigationRegion.md
- # - name: Qualifiers
- # href: Reference/Navigation/Qualifiers.md
- # - name: View Map
- # href: Reference/Navigation/ViewMap.md
- # - name: Route Map
- # href: Reference/Navigation/RouteMap.md
- # - name: Implement INavigator
- # href: Reference/Navigation/Navigator.md
- # - name: Implement IRequestHandler
- # href: Reference/Navigation/NavigationRequestHandler.md
+ - name: Navigation
+ href: xref:Reference.Navigation.Overview
+ items:
+ - name: Design
+ href: xref:Reference.Navigation.Design
+ - name: Navigation Region
+ href: xref:Reference.Navigation.Regions
+ - name: Qualifiers
+ href: xref:Reference.Navigation.Qualifiers
+ - name: INavigator
+ href: xref:Reference.Navigation.Navigator
+ - name: Implement IRequestHandler
+ href: xref:Reference.Navigation.RequestHandler