我們前面兩篇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: 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,就可以在模擬器上測試了。
代碼點擊這裡下載:
後記:
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執行個體。之後的博文會詳細解決這個問題。^_^