Xamarin形式 - 棱镜 - OnNavigatedTo召唤两次

时间:2018-05-09 13:04:54

标签: c# forms xamarin prism

所以,我用棱镜开发了一个App 2个月,刚才我意识到当我从MasterDetailPage中选择一个Item时,OnNavigatedTo方法一直在调用两次。

我不知道为什么会这样,我确定我错过了一些东西,但我大约两天试图解决它。

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

观察:当我在页面" A"我选择了页面" A"在主详细信息项列表中,OnNavigatedTo只被调用一次,但是当我在Page" B"我选择页面" A",OnNavigatedTo被调用两次。

从现在开始,谢谢你们,并对无知感到抱歉。

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
        }
    }

自定义导航页面MVVM:

public class PrincipalNavigationPageViewModel : ViewModelBase {
        public PrincipalNavigationPageViewModel(INavigationService navigationService) : base(navigationService) {
        }
    }

我在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!");
        }
    }

这三个例子的RegisterTypes:

    containerRegistry.RegisterForNavigation<PrincipalMasterDetailPage>();
containerRegistry.RegisterForNavigation<PrincipalNavigationPage>();
containerRegistry.RegisterForNavigation<NewPageTest>();

如何从PrincipalMasterDetailPageViewModel调用其他页面:

NavigationService.NavigateAsync(string.Format("PrincipalNavigationPage/{0}", item.TargetPageName));

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

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

            await NavigationService.NavigateAsync("LoginPage");
        }

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

await NavigationService.NavigateAsync("/PrincipalMasterDetailPage/PrincipalNavigationPage/WhateverPageIWantTo");

2 个答案:

答案 0 :(得分:2)

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

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

containerRegistry.RegisterForNavigation<NavigationPage>("Navigation");

为了能够在应用启动时执行以下操作:

 NavigationService.NavigateAsync($"Main/Navigation/Home");

但是,问题似乎在于,在没有指定特定ViewModel的情况下实例化此NavigationPage时,“ INavigationAware”事件以某种方式传播到MasterDetailPage的ViewModel,导致该事件上的事件被调用两次。 >

我通过使用以下ViewModel注册用于导航的NavigationPage来解决此问题:

    containerRegistry.RegisterForNavigation<NavigationPage, NavigationPageViewModel>("Navigation");

ViewModel本身没有什么特别之处:

using Prism.Commands;
using Prism.Mvvm;
using Prism.Navigation;
using System;
using System.Collections.Generic;
using System.Linq;
using Unity.Attributes;

namespace SocialRecipe.ViewModels
{
    public class NavigationPageViewModel : ViewModelBase
    {
        public NavigationPageViewModel()
        {

        }

        public override void OnNavigatedFrom(INavigationParameters parameters)
        {
        }

        public override void OnNavigatedTo(INavigationParameters parameters)
        {
        }

        public override void OnNavigatingTo(INavigationParameters parameters)
        {
        }
    }
}

通过这种方式,NavigationPage的事件被路由到NavigationPageViewModel,而不再传播到MasterDetailPage…

答案 1 :(得分:0)

我注意到Prism与以前的项目有一些不一致的结果。如果您现在只看到它并且之前有效,我会尝试回溯以查看您使用的版本是否不同。

https://github.com/PrismLibrary/Prism/issues