Windows Phone中使用Local DataBase与ISolateStorage—在MVVM模式下(三)
我们前面两篇Windows Phone中使用Local DataBase与ISolateStorage—在MVVM模式下(—)和Windows Phone中使用Local DataBase与ISolateStorage—在MVVM模式下(二)中完成了类IM发送消息的项目的前几步:
一.新建MVVMLight的Windows Phone Project
二.在Model中建立SQL CE数据库
三.建立MessageView.xaml界面以及绑定MessageViewModel
四.添加SendMessage的功能
五.添加MessageHistoryView的页面功能
其实到了这一步,除了加入Socket发送Message外(Socket我会重新写篇文章来讲解),我们的任务已经基本完成了。在移动互联网时代,用户体验是王道,下面我们便从这一点开始讨论墓碑:
六.完善用户体验
首先我们看Windows Phone的程序生命周期:
WP7程序执行时按Start键切换到后台首先会进入Dormant状态,可以理解为占用内存,但不在后台运行,此时程序可以快速切换回来。这时候我们不用做任何操作,WP7如果内存不够用了(Mango貌似允许5个程序处于Dormant状态),会将后台程序占用的内存释放掉,即进入Tombstoned(墓碑)状态。进入墓碑时界面上的信息如果不做保存机制,按Back键从墓碑机制返回时界面上的信息会丢失,这时候用户会感到很困惑:难道WP7不支持多任务?我只不过想暂停一下程序,为什么信息丢失了?
来看我们期望的是如下图:
但是实际操作的时候确实下图:(没有加入墓碑操作时)
如果想让程序从墓碑状态返回时同进入墓碑状态时保持一致,即用户察觉不到自己是否退出程序了,提供这么一种无缝的用户体验,就需要我们开发的时候加入一些保存当前状态的操作。官方推荐的是在Page进入和离开都会发生的OnNavigatedTo和OnNavigatedFrom事件中保存和恢复页面的数据。我们也推荐这种,但是现在我们要用的是Page的Load和Unload事件,在墓碑状态发生的时候,Load和Unload事件也是会发生的,这也提供了另外的墓碑操作的办法。所以我们只要新建两个Command,用来绑定Load和Unload事件即可。如图在PhoneApplicationPage上添加两个EventToCommand,设置EventName为Loaded,Command绑定MessageViewModel中新建的两个Command:
1: public ICommand PageLoadCommand{get;private set;}2: public ICommand PageUnloadCommand{get;private set;}
下面我们来保存Unload Page时SendMessage View的状态:这里只需要保存当前ListBox和Send Message输入框中的状态就好了。
看下面的代码:
1: PageUnloadCommand = new RelayCommand(2: () =>
3: {
4: IsolatedStorageSettings ISSetting = IsolatedStorageSettings.ApplicationSettings;
5: if (ISSetting.Contains("SendMessage"))6: {
7: ISSetting["SendMessage"] = SendMessage;8: }
9: else10: {
11: ISSetting.Add("SendMessage", SendMessage);12: }
13:
14:
15: if (ISSetting.Contains("MessageList"))16: {
17: ISSetting["MessageList"] = UserTable;18: }
19: else20: {
21: ISSetting.Add("MessageList", UserTable);22: }
23:
24: }
25: );
这样写键值的保存读取相对比较繁琐,可以抽象出相应函数时代码简洁,这里略过。
Load Page时读取之前保存的状态即可:
1: PageLoadCommand = new RelayCommand(2: () =>
3: {
4: IsolatedStorageSettings ISSetting = IsolatedStorageSettings.ApplicationSettings;
5: if (ISSetting.Contains("SendMessage"))6: {
7: SendMessage = (string)ISSetting["SendMessage"];8: }
9: if (ISSetting.Contains("MessageList"))10: {
11: ObservableCollection<UserInfoTable> users = (ObservableCollection<UserInfoTable>)ISSetting["MessageList"];12: UserTable = users;
13: }
14:
15: }
16: );
这时候我们页面导航的墓碑机制已经添加,上述用户期望的功能已经完成。在Debug想测试墓碑的时候,可以在项目右键点击属性,进入项目属性页面勾选中
TombStone upon deactivation while debugging,就可以在模拟器上测试了。
代码点击这里下载:
后记:
1. 其实MVVM模式下,还可以在在App.xaml.cs的函数
private void Application_Deactivated(object sender, DeactivatedEventArgs e)
中保存ViewModel,这时候工作量会很大,不推荐这种做法;
2. Windows Phone与Android不同的是:程序执行时,按Home键返回主页后,点击Back键都会返回到刚才执行的程序;而点击Home键返回主页时,如果点击程序图标,Android同Back键一样,从内存读取缓存,回到刚才程序执行的地方,而Windows Phone则重新开始一个新的程序实例……这时候习惯了其他系统的用户会相对比较困惑。想同时可以执行多个程序实例时这个很方便,但是如果同一时刻只允许一个实例,并且希望点击图标如果点击Back键操作时,就要由我们开发人员多增加一些操作。除了上述说的墓碑外,我们还要保存当前打开的Page的Uri或其他标志,在墓碑或者异常退出时保存到IsolateStorage中,然后在
private void Application_Launching(object sender, LaunchingEventArgs e)
函数中判断是从墓碑状态恢复,还是重新开一个新的App实例。之后的博文会详细解决这个问题。^_^