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的程序生命周期:

image

     WP7程序执行时按Start键切换到后台首先会进入Dormant状态,可以理解为占用内存,但不在后台运行,此时程序可以快速切换回来。这时候我们不用做任何操作,WP7如果内存不够用了(Mango貌似允许5个程序处于Dormant状态),会将后台程序占用的内存释放掉,即进入Tombstoned(墓碑)状态。进入墓碑时界面上的信息如果不做保存机制,按Back键从墓碑机制返回时界面上的信息会丢失,这时候用户会感到很困惑:难道WP7不支持多任务?我只不过想暂停一下程序,为什么信息丢失了?

来看我们期望的是如下图:

 

FL2H@)]5B3P}M78QEFYUP3C

 

 

但是实际操作的时候确实下图:(没有加入墓碑操作时)

 

O`UY4%O`IEVP{KK0X`PDA1J

 

 

      如果想让程序从墓碑状态返回时同进入墓碑状态时保持一致,即用户察觉不到自己是否退出程序了,提供这么一种无缝的用户体验,就需要我们开发的时候加入一些保存当前状态的操作。官方推荐的是在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;}

AWMD5G%CI[D(25R~8})AA0YCN_BS~EXF(ZL%FYGUO_}D%W

 

 

    下面我们来保存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:         else
  10:         {
  11:             ISSetting.Add("SendMessage", SendMessage);
  12:         }
  13:  
  14:  
  15:         if (ISSetting.Contains("MessageList"))
  16:         {
  17:             ISSetting["MessageList"] = UserTable;
  18:         }
  19:         else
  20:         {
  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,就可以在模拟器上测试了。

GHN2Y~T$H4)5{$[8VVZ5J68

 

代码点击这里下载:

后记:

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实例。之后的博文会详细解决这个问题。^_^

posted @ 2012-01-19 16:16  梦回千秋云断  阅读(1355)  评论(0编辑  收藏  举报