Xamarin.Forms, используя Prism.Forms NavigationService
Я пытаюсь реализовать сценарий входа в систему с помощью форм Xamarin и Prism.
Корневая страница моего приложения является страницей MasterDetail (HomeMasterDetailPage
); это используется для предоставления бокового меню.
То, что я пытаюсь сделать, это иметь HomeMasterDetailPage
страница показывается с Контентом, установленным в экземпляр LoginPage
, Когда пользователь входит в систему, содержимое должно измениться на экземпляр HomeDetailContentPage
, Не должно быть возможности вернуться к LoginPage
используя кнопку назад.
Я использую 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);
}
Насколько я понимаю, использование абсолютного Uri должно привести к сбросу навигации, чтобы новое расположение страниц (/NavigationPage/HomeMasterDetailPage/HomeDetailContentPage) находилось в верхней и нижней части стека, что позволило мне затем двигаться вперед оттуда. Вместо этого я получаю необработанное исключение (на Android 7.0).
Что я делаю неправильно?
Примечание. Все примеры, которые я вижу, имеют MasterDetailPage
в корне с Контентом, установленным в NavigationPage/ContentPage
; когда я пытаюсь это сделать, я не получаю исключений, однако боковое меню в MasterDetailPage
- когда вы нажимаете на "гамбургер", боковое меню скользит по всему (включая строку действий / заголовок), и единственный способ очистить его - это нажать за боковое меню, которое скользит, тогда как когда я показываю MasterDetailPage
в пределах NavigationPage
боковое меню скользит под панелью действий / заголовка, и гамбургер превращается в стрелку, которую можно нажать, чтобы снова скрыть боковое меню.
1 ответ
Я не могу сказать, что проверил этот точный сценарий. Однако, если ваш LoginPage является деталью MasterDetailPage, вы можете не захотеть выполнять навигацию из LoginPage. Вы могли бы вместо этого создать SuccessfulLoginEvent
, который вы бы затем опубликовать с LoginPage с помощью IEventAggregator
, и вы бы подписались на ViewModel вашего MasterDetailPage. Затем вы можете выполнить навигацию как _navigationService.NavigateAsync("NavigationPage/ViewA")
и он должен сбросить детализацию так, чтобы кнопка "назад" не доставляла вас на страницу входа.
Кроме того, вы можете просто выполнить абсолютную навигацию, которая имеет эффект:Application.Current.MainPage = new MyPage()
,
Чтобы сделать это, вы можете сделать навигацию из любого места, как:_navigationService.NavigateAsync("/MyMasterDetailPage/NavigationPage/ViewA")