Xamarin.Forms,使用 Prism.Forms 导航服务
Xamarin.Forms, using the Prism.Forms NavigationService
我正在尝试使用 Xamarin Forms 和 Prism 实现登录方案。
我的应用程序根页面是一个MasterDetail页面(HomeMasterDetailPage
);这用于提供侧边菜单。
我想要做的是将显示 Content 的 HomeMasterDetailPage
页面设置为 LoginPage
的实例。当用户登录时,Content 应更改为 HomeDetailContentPage
的实例。使用后退按钮 return 到 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>();
}
}
如果用户尚未登录,这会在 HomeMasterDetailPage
中正确显示 LoginPage
,如果用户已登录,则会在 HomeMasterDetailPage
中正确显示 HomeDetailContentPage
上。
实际登录时出现问题;以下是 LoginPage
...
的视图模型中的代码
protected async Task ExecuteLoginCommand() {
Uri uri = new Uri($"/{nameof(NavigationPage)}/{nameof(HomeMasterDetailPage)}/{nameof(HomeDetailContentPage)}", UriKind.Absolute);
await this.navigationService.NavigateAsync(uri);
}
据我了解,通过使用绝对 Uri,这应该会重置导航,以便新页面排列 (/NavigationPage/HomeMasterDetailPage/HomeDetailContentPage) 位于堆栈的顶部和底部,然后我可以从那里。相反,我收到一个未处理的异常(在 Android 7.0)。
我做错了什么?
注意:我看到的所有示例在根部都有 MasterDetailPage
,Content 设置为 NavigationPage/ContentPage
;当我尝试这个时,我没有得到异常,但是侧边菜单在 MasterDetailPage
中的操作不同 - 当你点击 "hamburger" 侧边菜单滑入所有内容(包括 action/title 栏) 清除它的唯一方法是点击滑入的侧边菜单外部,而当我在 NavigationPage
中显示 MasterDetailPage
时,侧边菜单滑入 action/title 栏下方并且汉堡包变为一个箭头,您可以单击它以再次隐藏侧边菜单。
我不能说我已经测试过这个确切的场景。但是,如果您的 LoginPage 是 MasterDetailPage 的 Detail,您可能不想从 LoginPage 执行导航。您可以创建一个 SuccessfulLoginEvent
,然后使用 IEventAggregator
从 LoginPage 发布它,然后您将在 MasterDetailPage 的 ViewModel 上订阅。然后您可以按 _navigationService.NavigateAsync("NavigationPage/ViewA")
执行导航,它应该重置详细信息,这样后退按钮就不会将您带到登录页面。
或者,您可以简单地执行具有以下效果的绝对导航:
Application.Current.MainPage = new MyPage()
。
为此,您可以从任何地方进行导航,如下所示:
_navigationService.NavigateAsync("/MyMasterDetailPage/NavigationPage/ViewA")
我正在尝试使用 Xamarin Forms 和 Prism 实现登录方案。
我的应用程序根页面是一个MasterDetail页面(HomeMasterDetailPage
);这用于提供侧边菜单。
我想要做的是将显示 Content 的 HomeMasterDetailPage
页面设置为 LoginPage
的实例。当用户登录时,Content 应更改为 HomeDetailContentPage
的实例。使用后退按钮 return 到 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>();
}
}
如果用户尚未登录,这会在 HomeMasterDetailPage
中正确显示 LoginPage
,如果用户已登录,则会在 HomeMasterDetailPage
中正确显示 HomeDetailContentPage
上。
实际登录时出现问题;以下是 LoginPage
...
protected async Task ExecuteLoginCommand() {
Uri uri = new Uri($"/{nameof(NavigationPage)}/{nameof(HomeMasterDetailPage)}/{nameof(HomeDetailContentPage)}", UriKind.Absolute);
await this.navigationService.NavigateAsync(uri);
}
据我了解,通过使用绝对 Uri,这应该会重置导航,以便新页面排列 (/NavigationPage/HomeMasterDetailPage/HomeDetailContentPage) 位于堆栈的顶部和底部,然后我可以从那里。相反,我收到一个未处理的异常(在 Android 7.0)。
我做错了什么?
注意:我看到的所有示例在根部都有 MasterDetailPage
,Content 设置为 NavigationPage/ContentPage
;当我尝试这个时,我没有得到异常,但是侧边菜单在 MasterDetailPage
中的操作不同 - 当你点击 "hamburger" 侧边菜单滑入所有内容(包括 action/title 栏) 清除它的唯一方法是点击滑入的侧边菜单外部,而当我在 NavigationPage
中显示 MasterDetailPage
时,侧边菜单滑入 action/title 栏下方并且汉堡包变为一个箭头,您可以单击它以再次隐藏侧边菜单。
我不能说我已经测试过这个确切的场景。但是,如果您的 LoginPage 是 MasterDetailPage 的 Detail,您可能不想从 LoginPage 执行导航。您可以创建一个 SuccessfulLoginEvent
,然后使用 IEventAggregator
从 LoginPage 发布它,然后您将在 MasterDetailPage 的 ViewModel 上订阅。然后您可以按 _navigationService.NavigateAsync("NavigationPage/ViewA")
执行导航,它应该重置详细信息,这样后退按钮就不会将您带到登录页面。
或者,您可以简单地执行具有以下效果的绝对导航:
Application.Current.MainPage = new MyPage()
。
为此,您可以从任何地方进行导航,如下所示:
_navigationService.NavigateAsync("/MyMasterDetailPage/NavigationPage/ViewA")