Global Navigation Event Handler
dansiegel opened this issue · comments
Description
Due to Navigation being Page based with Xamarin.Forms -> .NET Maui, the Navigation Service has a hard requirement that it can not be a Singleton. This creates a complication as there has been no good way of dealing with Navigation on a global basis. While the Page based navigation requirement is not changing, what we can do is expose NavigationEvent that can be published with Prism's IEventAggregator. Consuming applications can then either listen for and respond to the event. We could also introduce a plugin package to wrap this into an IObservable. As the event would contain the full context of the navigation this would also help us to ensure that you could maintain the current Navigation Uri.
Proposal
public enum NavigationType
{
Navigate,
GoBack,
GoToRoot,
}
public record NavigationContext
{
public NavigationType Type { get; init; }
// Only has a value when NavigationType is Navigate
public Uri? RequestUri { get; init; }
public INavigationParameters Parameters { get; init; }
public INavigationResult Result { get; init; }
}
public class NavigationEvent : PubSubEvent<NavigationContext> { }
Implementation
Currently Prism's Navigation Service has a number of places where we return the INavigationResult
typically something like:
return new NavigationResult { Success = true };
This would be updated to call a helper method which would return the NavigationResult and publish the event something like:
// Called by GoBack & GoToRoot
protected INavigationResult Notify(NavigationType type, INavigationParameters parameters, INavigationResult result)
{
_ea.GetEvent<NavigationEvent>().Publish(new NavigationContext
{
Type = type,
Parameters = parameters,
Result = result,
});
return result;
}
// called by Navigate
protected INavigationResult Notify(Uri uri, INavigationParameters parameters, INavigationResult result)
{
_ea.GetEvent<NavigationEvent>().Publish(new NavigationContext
{
Type = NavigationType.Navigate,
RequestUri = uri,
Parameters = parameters,
Result = result,
});
return result;
}
closed by #37