导航变化
当您尝试使用ModalEnforcement和MvvmEnforcement程序时,您可能会对模态页面未能保留任何信息感到不安。我们都遇到了导航到用于输入信息的页面的程序和网站,但是当您离开该页面然后再返回时,您输入的所有信息都消失了!这样的页面可能非常烦人。
即使在像ModalEnforcement和MvvmEnforcement这样的简单演示示例中,也可以通过仅创建模态页面的单个实例(可能在程序启动时 - 然后在整个过程中使用该单个实例)来非常轻松地解决该问题。
尽管这种解决方案显而易见,但它对于保留页面信息的问题并不是一个很好的通用方法。除最简单的情况外,应该避免使用这种技术。保持大量页面处于活动状态可能会导致内存问题,您必须小心避免在导航堆栈中多次使用相同的页面实例。
不过,这里是如何修改此技术的ModalEnforcementHomePage代码隐藏文件:
public partial class ModalEnforcementHomePage : ContentPage
{
ModalEnforcementModalPage modalPage = new ModalEnforcementModalPage();
public ModalEnforcementHomePage()
{
InitializeComponent();
}
async void OnGoToButtonClicked(object sender, EventArgs args)
{
await Navigation.PushModalAsync(modalPage);
}
}
ModalEnforcementHomePage将ModalEnforcementModalPage的实例保存为字段,然后始终将该单个实例传递给PushModalAsync。
在不太简单的应用程序中,这种技术很容易出错:有时,应用程序中的特定类型的页面可以从几个不同的页面导航到,这可能会导致两个单独的,不一致的ModalPage实例。
如果您需要在程序终止时保存程序的状态并在程序再次执行时将其还原,则此技术将完全崩溃。您无法自行保存和还原页面实例。通常是与页面关联的数据必须保存。
在现实生活中,ViewModels通常构成多页面应用程序中页面类型的主干,而应用程序保留页面数据的最佳方式是通过ViewModel而不是页面。
使用MvvmEnforcement可以演示在连续多次调用模式页面时维护页面状态的更好方法。首先,将属性添加到LittleViewModel的App页面,并在App构造函数中实例化该类:
namespace MvvmEnforcement
{
public class App : Application
{
public App()
{
ModalPageViewModel = new LittleViewModel();
MainPage = new NavigationPage(new MvvmEnforcementHomePage());
}
public LittleViewModel ModalPageViewModel { private set; get; }
__
}
}
由于LittleViewModel仅实例化一次,因此它会在应用程序的持续时间内维护信息。 然后,MvvmEnforcementModalPage的每个新实例都可以简单地访问此属性并将ViewModel对象设置为其BindingContext:
public partial class MvvmEnforcementModalPage : ContentPage
{
public MvvmEnforcementModalPage()
{
InitializeComponent();
LittleViewModel viewModel = ((App)Application.Current).ModalPageViewModel;
BindingContext = viewModel;
// Populate Picker Items list.
foreach (string language in viewModel.Languages)
{
picker.Items.Add(language);
}
}
__
}
当然,一旦程序终止,信息就会丢失,但App类也可以将这些信息保存在Application的Properties属性中 - 这是第6章“按钮点击”结束时PersistentKeypad程序中首次演示的技术 - 和 然后在应用程序再次启动时检索它。
保留数据和在页面之间传递数据的问题将占据本章后面部分的重点。