首页 > 解决方案 > 来自 Xamarin Forms App.OnAppLinkRequestReceived 的 Prism 导航使用

问题描述

我正在构建一个使用一些应用程序链接的应用程序。在下面的示例中,我想在用户激活电子邮件中的链接时打开一个 ResetPasswordPage。

protected override async void OnInitialized()
{
    InitializeComponent();
    await NavigationService.NavigateAsync("/NavigationPage/LoginPage");
}

protected override void OnAppLinkRequestReceived(Uri uri)
{
    if (uri.Host.EndsWith("site.nl", StringComparison.OrdinalIgnoreCase))
    {
        if (uri.AbsolutePath.StartsWith(@"/appname/resetpassword/"))
        {
            if (uri.Segments.Length == 4)
            {
                string resetCode = uri.Segments[3];

                NavigationParameters param = new();
                param.Add(NavConst.PasswordResetCode, resetCode);

                await NavigationService.NavigateAsync("ResetPasswordPage", param);
            }
        }
    }
}

此代码有效,但不是我所期望的(适用于 iOS 和 Android)。我希望 ResetPasswordPage 将添加到在 OnInitialized 中设置的导航堆栈中,以便它在导航栏中包含一个后退按钮,在这种情况下将用户带回登录页面。

但是,看起来导航堆栈被替换了。当显示 ResetPasswordPage 并且用户单击硬件后退按钮时,应用程序将关闭。但是,我希望它回到用户之前的位置。

我是不是不太了解一些导航概念,或者这可能是一个错误?

标签: xamarin.formsnavigationprism

解决方案


NavigationService 是 Prism 中用于 Xamarin.Forms 的一项相当独特的服务。它是为每个页面构建的新导航,导航堆栈取决于您从哪里导航。

例如,当您从 MasterDetailPage/FlyoutPage 的上下文中导航时,它知道您不是试图在该页面顶部推送模式,而是从 Detail/Flyout 的上下文开始。如果 NavigationService 不断更新页面上下文,那么注入该 MasterDetailPage/FlyoutPage 的 ViewModel 的导航服务将不知道它需要该页面作为导航的上下文。

您的问题最终是您正在从应用程序的上下文中导航,该应用程序的 NavigationService 没有设置页面。因此,即使是相对导航仍将具有绝对导航的效果,因此会重置 Application.MainPage,因为该 NavigationService 没有对另一个页面的上下文理解。

根据您的业务需求,您有几个不同的选择。一种是进行绝对导航,为您提供您正在寻找的导航堆栈。

或者,您可能希望获取当前显示的页面并更新 NavigationService 以了解它。在 App 类中,您可能会添加如下内容:

protected override void OnAppLinkRequestReceived(Uri uri)
{
    if (NavigationService is IPageAware pa)
    {
        page.Page = PageUtilities.GetCurrentPage(MainPage);
    }

    if (someCondition)
    {
        // This will now navigate from relatively from the page
        // returned by GetCurrentPage.
        NavigationService.NavigateAsync("SomeRelativeUrl")
            .OnNavigationError(HandleNavigationError);
    }
}

推荐阅读