Xamarin.forms 如何进入导航页面';s堆栈在选项卡式页面中
我正在使用MvvmCross和Xamarin表单。我的应用程序的主页是一个带有四个选项卡的Xamarin.forms 如何进入导航页面';s堆栈在选项卡式页面中,xamarin.forms,mvvmcross,Xamarin.forms,Mvvmcross,我正在使用MvvmCross和Xamarin表单。我的应用程序的主页是一个带有四个选项卡的MvxTabbedPage。每个选项卡都是导航页面,其中包含自己的内容页面。无论哪个选项卡是当前选项卡,对IMvxNavigationService的任何Navigate调用都会将页面推到第一个选项卡上 Application.Current.Hierarchy()的打印输出如下所示: Application Root HomePage(Tabbed) [0]: MvxNavigation
MvxTabbedPage
。每个选项卡都是导航页面,其中包含自己的内容页面。无论哪个选项卡是当前选项卡,对IMvxNavigationService
的任何Navigate
调用都会将页面推到第一个选项卡上
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)
从第二个选项卡启动导航
至详细信息页面
,将导致此层次结构:
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(无代码隐藏):
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
公共类HomeViewModel:MvxViewModel
{
//束缚性质
列出选项卡视图模型;
公共列表选项卡视图模型
{
得到
{
返回选项卡视图模型;
}
设置
{
_tabViewModels=值;
RaisePropertyChanged(()=>TabViewModels);
}
}
//束缚性质
公共选项卡DataTemplateSelector DataTemplateSelector
{
得到;
设置
}
// ...
公共类选项卡DataTemplateSelector:DataTemplateSelector
{
专用IMvxViewsContainer\u viewsContainer;
受保护的IMvxViewsContainer ViewsContainer
{
得到
{
如果(_viewsContainer==null)
_viewsContainer=Mvx.IoCProvider.Resolve();
返回视图容器;
}
}
字典缓存;
公共选项卡DataTemplateSelector()
{
Cache=新字典();
}
受保护的覆盖数据模板OnSelectTemplate(对象项,BindableObject容器)
{
WriteLine(“获取对象{0}的数据模板”,项);
DataTemplate _DataTemplate=null;
IMvxViewModel viewModel=项目作为IMvxViewModel;
类型viewType;
如果(项!=null)
{
if(Cache.ContainsKey(viewModel))
{
WriteLine(“缓存中的选项卡,返回缓存数据”);
_dataTemplate=缓存[viewModel];
}
其他的
{
viewType=ViewsContainer.GetViewType(viewModel.GetType());
WriteLine(“视图类型{0},视图模型{1}”,视图类型,视图模型);
_dataTemplate=新的dataTemplate(()=>
{
IMvxView视图=(IMvxView)Activator.CreateInstance(viewType);
view.DataContext=viewModel;
页面=(页面)视图;
MvxNavigationPage navigationPage=新建MvxNavigationPage(第页);
navigationPage.Title=页面.Title;
navigationPage.Icon=页面.Icon;
返回导航页面;
});
//缓存数据模板
缓存[viewModel]=\u数据模板;
}
}
返回数据模板;
}
}
//…HomeViewModel类结束
非常感谢您的帮助和指点
其他说明:
- 选项卡式页面具有以下属性:
[MvxTabbedPagePresentation(TabbedPosition.Root,NoHistory=true,WrapInNavigationPage=false)]
属性是ItemSource
对象的列表MvxViewModel
属性是一个数据模板,它实例化相应的ItemTemplate
,并将其包装在页面
中导航页面
- MvvmCross 6.2.2,Xamarin表格3.4
else
是否仅执行,则可以放置一个断点并查看代码once@LeoZhu控制台输出显示,加载选项卡式页面时,OnSelectTemplate()
会被调用四次(每个ViewModel对象一次),以后不再调用。在选项卡之间导航时不会再次调用它。
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