Xamarin.Forms,使用Prism.Forms NavigationService

时间:2017-04-28 15:55:24

标签: xamarin.forms prism-6

我正在尝试使用Xamarin Forms和Prism实现登录方案。

我的应用程序根页面是MasterDetail页面(HomeMasterDetailPage);这被用来提供侧面菜单。

我要做的是将显示 Content HomeMasterDetailPage页面设置为LoginPage的实例。用户登录时,内容应更改为HomeDetailContentPage的实例。不应该使用后退按钮返回LoginPage

我正在使用Prism Forms的NavigationService。

我的开始是这样的......

public partial class App : PrismApplication {

    public App(IPlatformInitializer initializer = null)
        : base(initializer) {
    }

    protected override void OnInitialized() {

        InitializeComponent();

        Uri uri = new Uri($"/{nameof(NavigationPage)}/{nameof(HomeMasterDetailPage)}/{nameof(HomeDetailContentPage)}", UriKind.Absolute);

        var settings = Container.Resolve<SettingsService>();
        if (!settings.DeviceUserID.HasValue)
            uri = new Uri($"/{nameof(NavigationPage)}/{nameof(HomeMasterDetailPage)}/{nameof(LoginPage)}", UriKind.Absolute);

        NavigationService.NavigateAsync(uri);
    }

    protected override void RegisterTypes() {

        Container.RegisterTypeForNavigation<NavigationPage>();

        Container.RegisterTypeForNavigation<LoginPage, LoginPageViewModel>();

        Container.RegisterTypeForNavigation<HomeMasterDetailPage, HomePageViewModel>();
        Container.RegisterTypeForNavigation<HomeMasterContentPage>();
        Container.RegisterTypeForNavigation<HomeDetailContentPage>();

    }

}

如果用户尚未登录,则会在LoginPage内正确显示HomeMasterDetailPage,如果用户已登录,则HomeDetailContentPage内的HomeMasterDetailPage会正确显示LoginPage

实际登录时会出现问题;以下是protected async Task ExecuteLoginCommand() { Uri uri = new Uri($"/{nameof(NavigationPage)}/{nameof(HomeMasterDetailPage)}/{nameof(HomeDetailContentPage)}", UriKind.Absolute); await this.navigationService.NavigateAsync(uri); } ...

的视图模型中的代码
MasterDetailPage

据我所知,通过使用绝对Uri,这应该重置导航,以便新的页面排列(/ NavigationPage / HomeMasterDetailPage / HomeDetailContentPage)位于堆栈的顶部和底部,允许我从那里向前移动。相反,我得到一个未处理的异常(在Android 7.0上)。

我做错了什么?

注意:我看到的所有示例都在根目录NavigationPage/ContentPage Content 设置为MasterDetailPage;当我尝试这个时,我没有例外,但是当你点击&#34;汉堡包时,侧边菜单在MasterDetailPage内的运作方式不同。侧边菜单滑过所有内容(包括动作/标题栏),清除它的唯一方法是点击侧滑菜单的外部,而当我在NavigationPage中显示var content = "" if content != ""{ print("have content") } for tag in tags{ let line = "\(tag.birdIndex),\(tag.isSeen)\n" content = content + line } if let path = Bundle.main.path(forResource: "birdLogVersion1", ofType: "csv"){ do { let data = try String(contentsOfFile: path, encoding: String.Encoding.utf8) print(data) }catch{ } //let url = NSURL(fileURLWithPath: path) do { try content.write(toFile: path, atomically: true, encoding: String.Encoding.utf8) //(to: url as URL, atomically: true, encoding: String.Encoding.utf8) print("tried write") }catch{ //error } }else{ } 时侧边菜单在动作/标题栏下方滑动,汉堡包变为箭头,您可以单击该箭头再次隐藏侧边菜单。

1 个答案:

答案 0 :(得分:0)

我无法说我已经测试了这个确切的情景。但是,如果您的LoginPage是MasterDetailPage的详细信息,您可能不希望从LoginPage执行导航。您可以创建一个SuccessfulLoginEvent,然后使用IEventAggregator从LoginPage发布,然后您将订阅MasterDetailPage的ViewModel。然后,您可以将导航作为_navigationService.NavigateAsync("NavigationPage/ViewA")执行,它应该重置详细信息,以便后退按钮不会将您带到LoginPage。

或者,您可以简单地执行具有以下效果的绝对导航: Application.Current.MainPage = new MyPage()

要做到这一点,你可以从任何地方进行导航: _navigationService.NavigateAsync("/MyMasterDetailPage/NavigationPage/ViewA")