Xamarin Forms - Prism - OnNavigedTo 调用两次

Mar*_*. H 3 c# forms prism xamarin

因此,我已经使用 prism 开发了一个应用程序 2 个月,现在我意识到当我从 MasterDetailPage 中选择一个项目时,OnNavigedTo 方法被调用了两次。

我不知道为什么会发生这种情况,我确信我错过了一些东西,但我大约需要两天时间来解决它。

我将在这里放置一些代码,如果你们需要更多信息,我可以发布更详细的信息。

观察:当我在页面“A”中并在主详细信息项目列表中选择页面“A”时,OnNavigedTo 仅被调用一次,但是当我在页面“B”中并选择页面“ A”,OnNavigedTo 被调用两次。

从现在起,谢谢你们,并对我的无知表示歉意。

MasterDetailPage MVVM:

public class PrincipalMasterDetailPageViewModel : ViewModelBase {
        public ObservableCollection<PrincipalMasterPageItem> MenuItems { get; set; }

        public PrincipalMasterDetailPageViewModel(INavigationService navigationService) : base(navigationService)
        {
            MenuItems = new ObservableCollection<PrincipalMasterPageItem>();
        }
        public async override void OnNavigatedTo(NavigationParameters parameters) {
            base.OnNavigatedTo(parameters);
            .. Here I'm calling an API, thats why I have the async
        }
    }
Run Code Online (Sandbox Code Playgroud)

自定义导航页面 MVVM:

public class PrincipalNavigationPageViewModel : ViewModelBase {
        public PrincipalNavigationPageViewModel(INavigationService navigationService) : base(navigationService) {
        }
    }
Run Code Online (Sandbox Code Playgroud)

当我在masterdetailpage项目列表中选择一个项目时实际显示的页面:

public class NewPageTestViewModel : ViewModelBase
    {
        public NewPageTestViewModel(INavigationService navigationService) : base(navigationService)
        {

        }

        public override void OnNavigatedTo(NavigationParameters parameters)
        {
            base.OnNavigatedTo(parameters);
            Debug.WriteLine("Calling twice HERE!");
        }
    }
Run Code Online (Sandbox Code Playgroud)

这三个例子的RegisterTypes:

    containerRegistry.RegisterForNavigation<PrincipalMasterDetailPage>();
containerRegistry.RegisterForNavigation<PrincipalNavigationPage>();
containerRegistry.RegisterForNavigation<NewPageTest>();
Run Code Online (Sandbox Code Playgroud)

如何从PrincipalMasterDetailPageViewModel调用其他页面:

NavigationService.NavigateAsync(string.Format("PrincipalNavigationPage/{0}", item.TargetPageName));
Run Code Online (Sandbox Code Playgroud)

在 App.cs 中,我开始如下,因为我首先需要登录页面:

protected override async void OnInitialized()
        {
            InitializeComponent();

            await NavigationService.NavigateAsync("LoginPage");
        }
Run Code Online (Sandbox Code Playgroud)

当用户登录时,它会像这样导航:

await NavigationService.NavigateAsync("/PrincipalMasterDetailPage/PrincipalNavigationPage/WhateverPageIWantTo");
Run Code Online (Sandbox Code Playgroud)

小智 5

我不知道是否有人仍然对此感兴趣,但我遇到了同样的问题并弄清楚发生了什么。

\n\n

我发现的所有代码示例都注册了一个 NavigationPage,如下所示:

\n\n
containerRegistry.RegisterForNavigation<NavigationPage>("Navigation");\n
Run Code Online (Sandbox Code Playgroud)\n\n

为了能够在应用程序启动时执行类似的操作:

\n\n
 NavigationService.NavigateAsync($"Main/Navigation/Home");\n
Run Code Online (Sandbox Code Playgroud)\n\n

然而,问题似乎是,当实例化此 NavigationPage 时没有分配特定的 ViewModel 时,“INavigationAware”事件会以某种方式传播到 MasterDetailPage 的 ViewModel,导致该事件被调用两次。

\n\n

我通过使用 ViewModel 注册用于导航的 NavigationPage 来修复此问题,如下所示:

\n\n
    containerRegistry.RegisterForNavigation<NavigationPage, NavigationPageViewModel>("Navigation");\n
Run Code Online (Sandbox Code Playgroud)\n\n

ViewModel 本身没有什么特别的:

\n\n
using Prism.Commands;\nusing Prism.Mvvm;\nusing Prism.Navigation;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing Unity.Attributes;\n\nnamespace SocialRecipe.ViewModels\n{\n    public class NavigationPageViewModel : ViewModelBase\n    {\n        public NavigationPageViewModel()\n        {\n\n        }\n\n        public override void OnNavigatedFrom(INavigationParameters parameters)\n        {\n        }\n\n        public override void OnNavigatedTo(INavigationParameters parameters)\n        {\n        }\n\n        public override void OnNavigatingTo(INavigationParameters parameters)\n        {\n        }\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

这样,NavigationPage 的事件将路由到 NavigationPageViewModel,并且不再传播到 MasterDetailPage\xe2\x80\xa6

\n