博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
第十八章:MVVM(十)
阅读量:7040 次
发布时间:2019-06-28

本文共 3983 字,大约阅读时间需要 13 分钟。

ViewModels和应用程序生命周期

在移动设备上的实际计算器程序中,一个重要特性涉及在程序终止时保存计算器的整个状态,并在程序再次启动时恢复它。

再次,ViewModel的概念似乎崩溃了。
当然,可以编写一些应用程序代码来访问ViewModel的公共属性并保存它们,但计算器的状态也取决于私有字段。 AdderViewModel的isSumDisplayed和accumulationSum字段对于恢复计算器的状态至关重要。
显而易见,AdderViewModel外部的代码无法保存和恢复AdderViewModel状态,而ViewModel不会暴露更多公共属性。只有一个类知道表示ViewModel的整个内部状态的必要条件,那就是ViewModel本身。
解决方案是让ViewModel定义保存和恢复其内部状态的公共方法。但是因为ViewModel应该努力与平台无关,所以这些方法不应该使用特定于特定平台的任何东西。例如,他们不应该访问Xamarin.Forms Application对象,然后向该Application对象的Properties字典添加项目(或从中检索项目)。这对于Xamarin.Forms来说太具体了。
但是,在任何.NET环境中都可以使用名为SaveState和RestoreState的方法中的通用IDictionary对象,这就是AdderViewModel实现这些方法的方式:

public class AdderViewModel : ViewModelBase{    __     public void SaveState(IDictionary
dictionary) { dictionary["CurrentEntry"] = CurrentEntry; dictionary["HistoryString"] = HistoryString; dictionary["isSumDisplayed"] = isSumDisplayed; dictionary["accumulatedSum"] = accumulatedSum; } public void RestoreState(IDictionary
dictionary) { CurrentEntry = GetDictionaryEntry(dictionary, "CurrentEntry", "0"); HistoryString = GetDictionaryEntry(dictionary, "HistoryString", ""); isSumDisplayed = GetDictionaryEntry(dictionary, "isSumDisplayed", false); accumulatedSum = GetDictionaryEntry(dictionary, "accumulatedSum", 0.0); RefreshCanExecutes(); } public T GetDictionaryEntry
(IDictionary
dictionary, string key, T defaultValue) { if (dictionary.ContainsKey(key)) return (T)dictionary[key]; return defaultValue; }}

涉及保存和恢复此状态的AddingMachine中的代码主要在App类中实现。 App类使用当前Application类的Properties字典实例化AdderViewModel并调用RestoreState。 然后将AdderViewModel作为参数传递给AddingMachinePage构造函数:

public class App : Application{    AdderViewModel adderViewModel;    public App()    {        // Instantiate and initialize ViewModel for page.        adderViewModel = new AdderViewModel();        adderViewModel.RestoreState(Current.Properties);        MainPage = new AddingMachinePage(adderViewModel);    }    protected override void OnStart()    {        // Handle when your app starts.    }    protected override void OnSleep()    {        // Handle when your app sleeps.        adderViewModel.SaveState(Current.Properties);     }    protected override void OnResume()    {        // Handle when your app resumes.    }}

App类还负责在处理OnSleep方法期间在AdderViewModel上调用SaveState。

AddingMachinePage构造函数只需要将AdderViewModel的实例设置为页面的BindingContext属性。 代码隐藏文件还管理纵向和横向布局之间的切换:

public partial class AddingMachinePage : ContentPage{    public AddingMachinePage(AdderViewModel viewModel)    {        InitializeComponent();        // Set ViewModel as BindingContext.        BindingContext = viewModel;    }    void OnPageSizeChanged(object sender, EventArgs args)    {        // Portrait mode.        if (Width < Height)        {            mainGrid.RowDefinitions[1].Height = GridLength.Auto;            mainGrid.ColumnDefinitions[1].Width = new GridLength(0, GridUnitType.Absolute);            Grid.SetRow(keypadGrid, 1);            Grid.SetColumn(keypadGrid, 0);        }        // Landscape mode.        else        {            mainGrid.RowDefinitions[1].Height = new GridLength(0, GridUnitType.Absolute);            mainGrid.ColumnDefinitions[1].Width = GridLength.Auto;            Grid.SetRow(keypadGrid, 0);            Grid.SetColumn(keypadGrid, 1);        }    }}

AddingMachine程序演示了一种处理ViewModel的方法,但这不是唯一的方法。或者,App可以实例化AdderViewModel,但是可以定义AddingMachineMode的构造函数可以访问的AdderViewModel类型的属性。

或者,如果您希望页面完全控制ViewModel,您也可以这样做。 AddingMachinePage可以定义自己的OnSleep方法,该方法是从App类中的OnSleep方法调用的,页面类也可以处理AdderViewModel的实例化以及调用RestoreState和SaveState方法。但是,对于多页应用程序,这种方法可能会变得有些笨拙。
在多页面应用程序中,每个页面可能都有单独的ViewModel,可能来自ViewModel,其属性适用于整个应用程序。在这种情况下,您需要使用相同的字典键来避免使用相同名称的属性来保存每个ViewModel的状态。您可以使用包含类名的更广泛的字典键,例如“AdderViewModel.CurrentEntry”。
虽然数据绑定和ViewModel的功能和优势现在应该很明显,但是当与Xamarin.Forms ListView一起使用时,这些功能真的很开心。 这将在下一章中讨论。

转载地址:http://bwaal.baihongyu.com/

你可能感兴趣的文章
使用 github pages, 快速部署你的静态网页
查看>>
react 之 state 对象
查看>>
Java中的锁原理、锁优化、CAS、AQS
查看>>
“智能厨电+渠道精耕”,华帝迈出“关键一步”
查看>>
Scrapy爬虫(2)爬取新浪旅游图片
查看>>
Nginx反向代理以及负载均衡配置
查看>>
巨头抢滩视频云 金山云稳坐头把交椅
查看>>
索尼富士康领投,AR显示技术厂商Digilens获得2200万美元融资
查看>>
Qt5 GUI 开发的应用易受远程代码执行漏洞的影响
查看>>
搞懂Java动态代理
查看>>
「镁客·请讲」NXROBO林天麟:我们分三步走,首先要做的就是打通机器人行业的产业链...
查看>>
Zcan无线扫描鼠标,滑哪扫哪
查看>>
NTKO使用说明
查看>>
django实现目录上传(最简单的方法)
查看>>
数组是同类型值的集合
查看>>
看透 : 解密身体语言隐藏的密码
查看>>
单例和原型模式-创建型
查看>>
还在吐槽VR的缺点?这些科技公司已经开始打脸了
查看>>
分布式消息队列中间件系列研究之阿堂教程(进阶篇)
查看>>
Linux常用快捷键
查看>>