如何在选项卡式页面内推入导航页面的堆栈

时间:2019-02-15 17:48:03

标签: xamarin.forms mvvmcross

我正在使用MvvmCross和Xamarin Forms。我的应用程序的主页是带有四个标签的MvxTabbedPage。每个选项卡都是包含其自己的内容页面的导航页面。无论哪个标签是当前标签,对Navigate的任何IMvxNavigationService调用都将页面推到第一个标签上。

Application.Current.Hierarchy()的打印输出如下:

Application Root
 HomePage(Tabbed)
        [0]: MvxNavigationPage(Navigation)
                          [0]: FirstPage(Content)
        [1]: MvxNavigationPage(Navigation)
                          [0]: SecondPage(Content)
        [2]: MvxNavigationPage(Navigation)
                          [0]: ThirdPage(Content)
        [3]: MvxNavigationPage(Navigation)
                          [0]: FourthPage(Content)

从第二个选项卡启动NavigateDetailsPage会导致此层次结构:

Application Root
 HomePage(Tabbed)
        [0]: MvxNavigationPage(Navigation)
                          [0]: FirstPage(Content)
                          [1]: DetailsPage(Content)
        [1]: MvxNavigationPage(Navigation)
                          [0]: SecondPage(Content)
        [2]: MvxNavigationPage(Navigation)
                          [0]: ThirdPage(Content)
        [3]: MvxNavigationPage(Navigation)
                          [0]: FourthPage(Content)

为了进行调试,我在MvxTabbedPage上的CurrentPageChanged事件上附加了一个处理程序,并且可以确认CurrentPage的更新正确。我还尝试了TabbedPage的设置WrapInNavigationPage = true,但这会导致不良的导航行为。

HomePage.xaml(无代码隐藏):

<?xml version="1.0" encoding="UTF-8"?>
<views:MvxTabbedPage
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:views="clr-namespace:MvvmCross.Forms.Views;assembly=MvvmCross.Forms"
    xmlns:mvx="clr-namespace:MvvmCross.Forms.Bindings;assembly=MvvmCross.Forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:local="clr-namespace:Ketchup.Core.Views"
    xmlns:viewModels="clr-namespace:Ketchup.Core.ViewModels;assembly=Ketchup.Core" 
    x:Class="Ketchup.Core.Views.HomePage"
    x:TypeArguments="viewModels:HomeViewModel" 
    ItemTemplate="{mvx:MvxBind DataTemplateSelector}"
    ItemsSource="{mvx:MvxBind TabViewModels}"
    xmlns:android="clr-namespace:Xamarin.Forms.PlatformConfiguration.AndroidSpecific;assembly=Xamarin.Forms.Core"
    android:TabbedPage.ToolbarPlacement="Bottom"
    >

</views:MvxTabbedPage>

HomePageViewModel.cs

    public class HomeViewModel : MvxViewModel
    {
        // Bound Property
        List<IMvxViewModel> _tabViewModels;
        public List<IMvxViewModel> TabViewModels
        {
            get
            {
                return _tabViewModels;
            }
            set
            {
                _tabViewModels = value;
                RaisePropertyChanged(() => TabViewModels);
            }
        }
        // Bound Property
        public TabDataTemplateSelector DataTemplateSelector
        {
            get;
            set;
        }
        // ...

        public class TabDataTemplateSelector : DataTemplateSelector
        {

            private IMvxViewsContainer _viewsContainer;
            protected IMvxViewsContainer ViewsContainer
            {
                get
                {
                    if (_viewsContainer == null)
                        _viewsContainer = Mvx.IoCProvider.Resolve<IMvxViewsContainer>();
                    return _viewsContainer;
                }
            }

            Dictionary<IMvxViewModel, DataTemplate> Cache;

            public TabDataTemplateSelector()
            {

                Cache = new Dictionary<IMvxViewModel, DataTemplate>();

            }

            protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
            {

                Console.WriteLine("Get Data Template for Object {0}", item);

                DataTemplate _dataTemplate = null;

                IMvxViewModel viewModel = item as IMvxViewModel;
                Type viewType;

                if (item != null)
                {

                    if (Cache.ContainsKey(viewModel))
                    {

                        Console.WriteLine("Tab in cache, returning cached data.");
                        _dataTemplate = Cache[viewModel];

                    }
                    else
                    {

                        viewType = ViewsContainer.GetViewType(viewModel.GetType());

                        Console.WriteLine("View Type {0}, ViewModel {1}", viewType, viewModel);

                        _dataTemplate = new DataTemplate(() =>
                        {

                            IMvxView view = (IMvxView)Activator.CreateInstance(viewType);
                            view.DataContext = viewModel;
                            Page page = (Page)view;

                            MvxNavigationPage navigationPage = new MvxNavigationPage(page);
                            navigationPage.Title = page.Title;
                            navigationPage.Icon = page.Icon;

                            return navigationPage;

                        });
                        // Cache DataTemplate
                        Cache[viewModel] = _dataTemplate;
                    }
                }
                return _dataTemplate;
                }
        }
       // ... End of HomeViewModel class

非常感谢任何帮助或指针!

其他说明:

  • 选项卡式页面具有以下属性:[MvxTabbedPagePresentation(TabbedPosition.Root, NoHistory = true, WrapInNavigationPage = false)]

  • ItemSource属性是MvxViewModel个对象的列表。

  • ItemTemplate属性是一个数据模板,它实例化相应的Page并将其包装在NavigationPage中。

  • MvvmCross 6.2.2,Xamarin形式3.4

0 个答案:

没有答案