使用Xamarin.Forms进行导航

使用Xamarin.Forms进行导航,xamarin,mvvm,xamarin.forms,Xamarin,Mvvm,Xamarin.forms,试图找到使用Xamarin.Forms页面实现导航的最佳方法 这是我的UI导航图 我正在使用mvvm。每个ViewModel都使用INavigationService填充 public class NavigationService : INavigationService { private readonly NavigationPage navigationPage; private const string PageNameTemplate = "Mmv.MMTrave

试图找到使用Xamarin.Forms页面实现导航的最佳方法

这是我的UI导航图

我正在使用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都有用于异步初始化的onnVagateTo()和OnNavigateFrom()方法。 当应用程序启动时,我将app.cs中的MainPage属性设置为NavigationService中的navigationPage

问题1

通过页面#1-#3实现导航(在UI导航图上) 我使用setAndNavigateTootPage方法

例如,当用户从第1页介绍导航到第2页帐户时。

我调用导航属性的InsertPageBefore()方法。

然后是PopToRootAsync()方法。

我找到了实现这一目标的新方法。只需将App.cs中的MainPage属性设置为新页面

请告诉我您的意见哪种方式更好?

  • 使用setAndNavigateTootPage

  • 在App.cs中设置主页属性

问题2

有一个MasterDetailPage(#5)

问题是,当我从第3页主菜单导航到第5页主菜单时,根据我当前的实现,我有以下几点:

根据Xamarin文件:

用MasterDetailPage填充NavigationPage不是一个好主意


我应该更改导航服务并使用App.cs中的MainPage属性,而不是将所有内容都放在NavigationPage中,不是吗?

是的,您是对的,您必须使用MainPage属性才能使用正确的导航系统。但在android平台上,你可能会遇到导航方面的问题。(我记得有些导航操作在android上不起作用)