FreshMVVM 在 ContentPage 和 TabbedPage 之间切换导航堆栈
Posted
技术标签:
【中文标题】FreshMVVM 在 ContentPage 和 TabbedPage 之间切换导航堆栈【英文标题】:FreshMVVM Switching Navigation Stacks Between ContentPage and TabbedPage 【发布时间】:2021-03-06 17:57:58 【问题描述】:我正在将应用转换为使用非 MVVM 格式的 FreshMVVM。当应用程序启动时,会出现一个登录页面,然后在登录后,会出现一个标签页,其中包含从每个标签页上的按钮调用的模式页面。
鉴于我正在遵循的过程,我认为这将是使用 Michael Ridland 的过程来切换 NavigationStacks (https://github.com/rid00z/FreshMvvm#switching-out-navigationstacks-on-the-xamarinforms-mainpage) 的完美选择,但这些步骤似乎缺少很多重要的说明,这些步骤不在 GitHub 上的示例应用程序中。
在我的App.xaml.xs
文件中,我有以下代码:
public App()
InitializeComponent();
var loginPage = FreshMvvm.FreshPageModelResolver.ResolvePageModel<LoginPageModel>();
var loginContainer = new STNavigationContainer(loginPage, NavigationContainerNames.AuthenticationContainer);
var homePageViewContainer = new FreshTabbedNavigationContainer(NavigationContainerNames.MainContainer);
MainPage = loginContainer;
public FreshTabbedNavigationContainer(string navigationServiceName)
NavigationServiceName = navigationServiceName;
RegisterNavigation();
protected void RegisterNavigation()
FreshIOC.Container.Register<IFreshNavigationService>(this, NavigationServiceName)
public void SwitchOutRootNavigation(string navigationServiceName)
IFreshNavigationService rootNavigation =
FreshIOC.Container.Resolve<IFreshNavigationService>(navigationServiceName);
public void LoadTabbedNav()
var tabbedNavigation = new FreshTabbedNavigationContainer();
tabbedNavigation.AddTab<CharactersPageModel>("Characters", "characters.png");
tabbedNavigation.AddTab<AdventuresPageModel>("Adventures", "adventures.png");
tabbedNavigation.AddTab<AccountPageModel>("Account", "account.png");
MainPage = tabbedNavigation;
public class NavigationContainerNames
public const string AuthenticationContainer = "AuthenticationContainer";
public const string MainContainer = "MainContainer";
这似乎与 ReadMe.md 中提供的步骤相匹配,但对 NavigationServiceName
的调用会返回错误,因为没有关于创建此类或它应该包含什么的说明,我也不清楚在哪里FreshTabbedNavigationContainer
或 SwitchOutRootNavigation
将被调用。
有没有人能够让它工作?我在这方面缺少哪些步骤?
编辑:我忘了我已经扩展了FreshNavigationContainter
类和FreshNavigationPage
类。这是我的扩展类:
STNavigationContainer:
public class STNavigationContainer : FreshNavigationContainer
public STNavigationContainer(Page page) : base(page)
public STNavigationContainer(Page page, string navigationPageName) : base(page, navigationPageName)
protected override Page CreateContainerPage(Page page)
if (page is NavigationPage || page is MasterDetailPage || page is TabbedPage)
return page;
return new STNavigationPage(page);
STNavigationPage:
public class STNavigationPage : NavigationPage
public STNavigationPage()
public STNavigationPage(Page page) : base(page)
BarBackgroundColor = Color.FromHex("#2DAFEB");
BarTextColor = Color.FromHex("#C9371D");
编辑 2:重新阅读 https://michaelridland.com/xamarin/implementing-freshmvvm-mvvm-xamarin-forms/ 和 Github 帖子,我发现我需要在自定义导航服务中执行此操作,所以这是我更新的代码。
App.xaml.cs:
public partial class App : Application
public static Account account = new Account();
public App()
InitializeComponent();
FreshIOC.Container.Register<IDatabaseService, DatabaseService>();
if (account.Equals(null))
LoadSingleNav();
else
LoadTabbedNav();
var navPage = new NavigationPage(new LoginPage())
BarBackgroundColor = Color.FromHex("#2DAFEB"),
BarTextColor = Color.FromHex("#C9371D")
;
NavigationPage.SetHasNavigationBar(navPage.CurrentPage, false);
MainPage = navPage;
MainPage = loginContainer;
public FreshTabbedNavigationContainer(string navigationServiceName)
NavigationContainerNames = navigationServiceName;
RegisterNavigation();
protected override void OnStart()
protected override void OnSleep()
protected override void OnResume()
CustomNavService.cs:
public class CustomNavService : NavigationPage, IFreshNavigationService
FreshTabbedNavigationContainer _tabbedNavigationPage;
Page _charactersPage, _adventuresPage, _accountPage;
public CustomNavService(Page page) : base (page)
NavigationServiceName = "CustomNavService";
LoadTabbedNav();
CreateLoginPage();
RegisterNavigation();
public string NavigationServiceName get; private set;
public void NotifyChildrenPageWasPopped()
throw new NotImplementedException();
public async Task PopPage(bool modal = false, bool animate = true)
if (modal)
await Navigation.PopModalAsync (animate);
else
await Navigation.PopAsync (animate);
public async Task PopToRoot(bool animate = true)
await Navigation.PopToRootAsync(animate);
public async Task PushPage(Page page, FreshBasePageModel model, bool modal = false, bool animate = true)
if (modal)
await Navigation.PushModalAsync(page, animate);
else
await Navigation.PushAsync(page, animate);
public Task<FreshBasePageModel> SwitchSelectedRootPageModel<T>() where T : FreshBasePageModel
IFreshNavigationService rootNavigation =
FreshIOC.Container.Resolve<IFreshNavigationService>(NavigationServiceName);
public void LoadTabbedNav()
_tabbedNavigationPage = new FreshTabbedNavigationContainer();
_charactersPage = _tabbedNavigationPage.AddTab<CharactersPageModel>("Characters", "characters.png");
_adventuresPage = _tabbedNavigationPage.AddTab<AdventuresPageModel>("Adventures", "adventures.png");
_accountPage = _tabbedNavigationPage.AddTab<AccountPageModel>("Account", "account.png");
this = _tabbedNavigationPage;
private void CreateLoginPage()
var loginPage = FreshPageModelResolver.ResolvePageModel<LoginPageModel>(null);
var loginContainer = new STNavigationContainer(loginPage, CustomNavService.NavigationContainerNames.AuthenticationContainer);
var homePageViewContainer = new FreshTabbedNavigationContainer(CustomNavService.NavigationContainerNames.MainContainer);
protected void RegisterNavigation()
FreshIOC.Container.Register<IFreshNavigationService>(this, NavigationServiceName);
public class NavigationContainerNames
public const string AuthenticationContainer = "AuthenticationContainer";
public const string MainContainer = "MainContainer";
我的自定义导航服务中的SwitchSelectedRootPageModel<T>
任务显示需要返回,我不太清楚LoadTabbedNav
应该包含什么this
;该示例显示 this.Detail
,但这显示为无效引用。
【问题讨论】:
【参考方案1】:查看我们的 FreshMvvm 实现,我们的 SwitchSelectedRootPageModel 如下所示:
public Task<FreshBasePageModel> SwitchSelectedRootPageModel<T>() where T : FreshBasePageModel
return Task.FromResult<FreshBasePageModel>(null);
我们的代码正确使用
this.Detail = _tabbedNavigationPage;
所以如果你得到一个无效的引用,肯定还有其他东西丢失了。
【讨论】:
以上是关于FreshMVVM 在 ContentPage 和 TabbedPage 之间切换导航堆栈的主要内容,如果未能解决你的问题,请参考以下文章
Xamarin Forms MvvM框架之FreshMvvM翻译一
Xamarin.Forms ContentPage生命周期的困惑
Xamarin XAML语言教程基本页面ContentPage占用面积
我可以在 TabbedPage 内的 ContentPage 中放置另一个 ContentPage 吗?