尝试使用Xamarin.Forms页面找到实现导航的最佳方式。
我正在使用mvvm。每个ViewModel都填充了INavigationService。
public class NavigationService : INavigationService
{
private readonly NavigationPage navigationPage;
private const string PageNameTemplate = "Mmv.MMTravel.CrossPlatform.Views.{0}, Mmv.MMTravel.CrossPlatform";
public NavigationService(NavigationPage page)
{
navigationPage = page;
}
public string CurrentPageKey
{
get
{
return navigationPage.CurrentPage.GetType().Name;
}
}
public async Task GoBackAsync()
{
await navigationPage.Navigation.PopAsync();
}
public async Task NavigateAsync(string pageKey, object parameter)
{
await CallOnNavigateFrom();
var page = CreatePage(pageKey);
await CallOnNavigateTo(page, parameter);
if (Device.OS == TargetPlatform.Android)
{
Device.BeginInvokeOnMainThread(() =>
{
navigationPage.Navigation.PushAsync(page);
});
}
else
{
await navigationPage.Navigation.PushAsync(page);
}
}
public async Task NavigateAsync(string pageKey)
{
await NavigateAsync(pageKey, null);
}
public async Task SetAndNavigateToRootPage(string pageKey, object parameter)
{
await CallOnNavigateFrom();
var page = CreatePage(pageKey);
await CallOnNavigateTo(page, parameter);
navigationPage.Navigation.InsertPageBefore(page, navigationPage.Navigation.NavigationStack.First());
await navigationPage.PopToRootAsync(false);
}
public async Task SetAndNavigateToRootPage(string pageKey)
{
await SetAndNavigateToRootPage(pageKey, null);
}
public async Task NavigateModalAsync(string pageKey, object parameter)
{
await CallOnNavigateFrom();
var page = CreatePage(pageKey);
await CallOnNavigateTo(page, parameter);
await navigationPage.Navigation.PushModalAsync(page);
}
public async Task NavigateModalAsync(string pageKey)
{
await NavigateModalAsync(pageKey, null);
}
public async Task GoBackModalAsync()
{
await navigationPage.Navigation.PopModalAsync();
}
private Page CreatePage(string pageKey)
{
var typeName = string.Format(PageNameTemplate, pageKey);
var pageType = Type.GetType(typeName);
var page = Activator.CreateInstance(pageType) as Page;
return page;
}
private async Task CallOnNavigateTo(Page page, object parameter)
{
var vm = page.BindingContext as INavigateAwareViewModel;
if (vm != null && !vm.IsBusy)
{
await vm.OnNavigatedTo(parameter).ConfigureAwait(false);
}
}
private async Task CallOnNavigateFrom()
{
if (navigationPage.CurrentPage != null)
{
var prevVM = navigationPage.CurrentPage.BindingContext as INavigateAwareViewModel;
if (prevVM != null && !prevVM.IsBusy)
{
await prevVM.OnNavigatedFrom().ConfigureAwait(false);
}
}
}
}
如您所见,我的NavigationService包含NavigationPage。因此,所有导航都通过NavigationPage中的Navigation属性进行。 此外,每个viewmodel都具有异步init的OnNvaigateTo()和OnNavigateFrom()方法。 当应用程序启动时,我将App.cs中的MainPage属性设置为NavigatioService中的navigationPage
问题#1
通过页面#1 - #3实现导航(在UI导航图上) 我使用 SetAndNavigateToRootPage 方法
例如,当用户从第1页INTRO导航到第2页ACCOUNT时。
我调用Navigation属性的InsertPageBefore()方法。
我找到了实现这一目标的新方法。只是将App.cs中的MainPage属性设置为新页面。
请告诉我您的意见哪条路更好?
使用SetAndNavigateToRootPage
在App.cs中设置MainPage属性
问题#2
有MasterDetailPage(#5)
问题是,当我从第3页MAIN NENU导航到第5页BurgerMenu时,根据我目前的实现,我有这个:
根据Xamarin的文件:
使用MasterDetailPage填充NavigationPage不是一个好主意......
我应该更改我的NavigationService并使用App.cs中的MainPage属性,而不是将所有内容都放在NavigationPage中,不应该吗?