我正在处理的项目包含以下结构:
启动应用后,用户会看到欢迎页面。此时用户有两种选择。他们可以登录或注册。如果登录== true;然后转到主详细页面。或者在注册时,如果注册==成功,则转到登录页面并按照相同的流程进入主详细信息页面。
-> Login Page ||
Welcome Page >> ================== || => MasterDetailPage
-> Register Page -> Login page ||
我正在使用MVVM Light通过INavigationService处理我的导航堆栈,因为我的UI和业务逻辑通过MVVM分离。一切都很好,除了我需要重置导航堆栈,这样用户将无法在" MasterDetailPage"之前访问任何页面。如上所示。现在,用户可以使用Android上的硬件返回按钮或从iOS上的左边缘轻扫,返回登录或注册或之前的任何页面。另外,顶部导航栏上还有一个导航后退按钮。
我的App.cs看起来像这样
public App()
{
var nav = RegisterNavigationService();
SimpleIoc.Default.Register<INavigationService>(() => nav);
InitializeComponent();
var initialPage = new NavigationPage(new WelcomePage());
nav.Initialize(initialPage);
MainPage = initialPage;
}
private NavigationService RegisterNavigationService()
{
var nav = new NavigationService();
nav.Configure(Locator.LoginForm, typeof(LoginForm));
nav.Configure(Locator.RegisterSuccessPage, typeof(RegisterSuccessPage));
nav.Configure(Locator.RegistrationForm, typeof(RegistrationForm));
nav.Configure(Locator.WelcomePage, typeof(WelcomePage));
nav.Configure(Locator.MasterMainPage, typeof(MasterMainPage));
return nav;
}
在我的视图模型中,我处理这样的导航命令:
public class LoginFormViewModel : BaseViewModel
{
private readonly INavigationService _navigationService;
public Command NavigateToMainPage { get; }
public LoginFormViewModel(INavigationService navigationService)
{
_navigationService = navigationService ?? throw new ArgumentNullException("navigationService");
NavigateToMainPage = new Command(() => NavigateToMainApp());
}
private void NavigateToMainApp()
{
_navigationService.NavigateTo(Locator.MasterMainPage);
}
}
最后,我的NavigationService.cs看起来像这样......我几乎没碰过这部分代码......我唯一尝试过的就是&#39; ClearNavigationStack&#39;方法,但这是一个失败。
public class NavigationService : INavigationService, INavigationServiceExtensions
{
private Dictionary<string, Type> _pagesByKey = new Dictionary<string, Type>();
private NavigationPage _navigation;
public string CurrentPageKey
{
get
{
lock (_pagesByKey)
{
if (_navigation.CurrentPage == null)
{
return null;
}
var pageType = _navigation.CurrentPage.GetType();
return _pagesByKey.ContainsValue(pageType)
? _pagesByKey.First(p => p.Value == pageType).Key
: null;
}
}
}
public void GoBack()
{
_navigation.PopAsync();
}
public void NavigateTo(string pageKey)
{
NavigateTo(pageKey, null);
}
public void NavigateTo(string pageKey, object parameter)
{
lock (_pagesByKey)
{
if (_pagesByKey.ContainsKey(pageKey))
{
ConstructorInfo constructor;
object[] parameters;
var type = _pagesByKey[pageKey];
if (parameter == null)
{
constructor = type.GetTypeInfo()
.DeclaredConstructors
.FirstOrDefault(c => !c.GetParameters().Any());
parameters = new object[] { };
}
else
{
constructor = type.GetTypeInfo()
.DeclaredConstructors
.FirstOrDefault(
c =>
{
var p = c.GetParameters();
return p.Count() == 1
&& p[0].ParameterType == parameter.GetType();
});
parameters = new[] { parameter };
}
if (constructor == null)
{
throw new InvalidOperationException("No suitable constructor found for page " + pageKey);
}
var page = constructor.Invoke(parameters) as Page;
_navigation.PushAsync(page);
}
else
{
throw new ArgumentException(
string.Format("No such page: {0}. Did you forget to call NavigationService.Configure?", pageKey), "pageKey");
}
}
}
public void Configure(string pageKey, Type pageType)
{
lock (_pagesByKey)
{
if (_pagesByKey.ContainsKey(pageKey))
{
_pagesByKey[pageKey] = pageType;
}
else
{
_pagesByKey.Add(pageKey, pageType);
}
}
}
public void ClearNavigationStack()
{
lock (_pagesByKey)
{
foreach (var pageKey in _pagesByKey.Keys)
{
_pagesByKey.Remove(pageKey);
}
}
}
public void Initialize(NavigationPage navigation)
{
_navigation = navigation;
}
}
我从以下git repo:https://github.com/mallibone/MvvmLightNavigation.XamarinForms
中取得了这一点遵循本教程: https://mallibone.com/post/xamarin.forms-navigation-with-mvvm-light
注意:这是个PCL。
我欢迎任何建议,因为过去两天我一直在讨论这个问题。
编辑:刚才,我已经设法隐藏了#34;通过将我的MainPage设置为类似
的导航堆栈App.Current.MainPage = new MasterMainPage();
但它看起来像一个代码味道,看起来像一个可怕的黑客。另外,我不太确定它是否会违反&#34;我正在遵循的概念...我想这个导航堆栈永远不会消失,因为我将在主细节页面内做其他导航堆栈。
答案 0 :(得分:1)
从图片中我看到您在导航页面中有Master / Detaied页面。 Xamarin并不建议这样做。我不知道你将如何在MVVM Light中做到这一点,但在常规表格中,你有几种选择来实现你想要的:
如果您需要返回登录或注册页面,请使用
p-value=0.7527
然后你可以popmodal回到它们但是在这种情况下硬件按钮仍然会带你登录。导航到主 - 详细信息页面后,可以使用方法2的一部分清除堆栈但要小心 - 如果页面是根目录和当前显示的页面,则无法从堆栈中删除页面,因此您只需在清除后定期导航堆栈登录页面不显示。 我不建议将该选项作为&#34;模态视图通常是临时的,并且只在屏幕上播放足够长的时间以便用户完成任务。&#34;
http://blog.adamkemp.com/2014/09/navigation-in-xamarinforms_2.html
如果您不需要返回,可以使用以下清除导航堆栈,它也会删除后退按钮
fitdistr(x, "gamma")