C# 管理狀態(tài)
與桌面應(yīng)用程序不同,應(yīng)用程序必須能隨時(shí)暫停。在用戶切換到另一個(gè)應(yīng)用程序或桌面時(shí),就會(huì)發(fā)生這種情況。所以它必須是一個(gè)由所有應(yīng)用程序處理的常見(jiàn)場(chǎng)景。當(dāng)應(yīng)用程序暫停時(shí),Windows將保存變量的值和數(shù)據(jù)結(jié)構(gòu),并在應(yīng)用程序恢復(fù)執(zhí)行時(shí)恢復(fù)它們,然而,應(yīng)用程序可能己經(jīng)暫停了較長(zhǎng)時(shí)間,所以如果數(shù)據(jù)(如新聞?wù)?隨著時(shí)間的推移而變化,就應(yīng)該在應(yīng)用程序恢復(fù)執(zhí)行時(shí)更新它。
暫停應(yīng)用程序時(shí),還應(yīng)該考慮調(diào)用應(yīng)用程序之間應(yīng)保存的任何數(shù)據(jù),如果應(yīng)用程序隨后由Windows或用戶終止了,就沒(méi)有機(jī)會(huì)這樣做。
應(yīng)用程序要暫停時(shí),會(huì)發(fā)送Suspending事件,應(yīng)該處理該事件。當(dāng)應(yīng)用程序恢復(fù)執(zhí)行時(shí),它將接收Resuming事件。處理這兩個(gè)事件,保存應(yīng)用程序的狀態(tài),就可以把應(yīng)用程序返回到暫停之前的狀態(tài),且用戶不會(huì)注意到什么。
試一試 從暫停中恢復(fù):Ch25Ex06
(1)回到前面的示例,并創(chuàng)建一個(gè)新類AppState:
using System.Collections.Generic;
namespace BasicNavigation
{
public static class AppState
{
private static Dietionary<string, bool> state = new Dictionary<string, bool>();
public static bool GetState(string pageName) => state.ContainsKey(pageName) ?
state[pageName] : false;
public static void SetState(string pageName, bool isBold)
{
if (state.ContainsKey(pageName))
state[pageName] = isBold;
else
state.Add(pageName, isBold);
}
public static void Save ()
{
var settings = Windows.Storage.ApplicationData.Current.RoamingSettings;
foreach (var key in state.Keys)
{
settings.Values[key] = state[key];
}
}
public static void Load{string pageName)
{
if (!state,ContainsKey(pageName) $$ Windows.Storage-ApplicationData.Current. RoamingSettings.Values.ContainsKey(pageName))
state.Add(pageName, (bool)Windows.Storage.ApplicationData.Current.
RoamingSettings.Values(pageName]);
}
}
}
(2)打開(kāi)app.xaml文件的代碼隱藏文件,在底部定位OnSuspending方法。添加AppState.Save(),如下所示:
private void OnSuspending(object sender, SuspendingEventArgs e)
{
var deferral = e.SuspendingOperation.GetDeferral{);
//TODO: Save application state and stop any background activity
AppState.Save();
deferral.Complete();
}
(3)在OnLaunched方法的底部、Window.Current.Activate();的前面添加如下代碼:
AppState.Load(typeof(BlankPagel).Name);
AppState.Load{typeof(BlankPage2).Name);
AppState.Load(typeof(BlankPage3).Name);
(4)進(jìn)入BlankPagel,在Page類上添加loaded事件,如下所示:
<Page
x:Class="BasicNavigation.BlankPagel"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:BasicNavigation"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" Loaded="Page_Loaded">
(5)實(shí)現(xiàn)事件:
private void Page_Loaded(object sender, RoutedEventArgs e)
{
toggleButtonBold.IsChecked = AppState.GetState{GetType().Name);
AppBarToggleButtonBold_Click(toggleButtonBold, new RoutedEventArgs());
}
(6)修改開(kāi)關(guān)按鈕的Click事件處理程序,在按下按鈕時(shí)保存頁(yè)面的狀態(tài):
private void AppBarToggleButtonBold_Click(object sender, RoutedEventArgs e)
{
AppState.SetState{GetType().Name, (bool)toggleButtonBold.IsChecked);
...
}
(7)對(duì)BlankPage2和BlankPage3重復(fù)步驟(4)到步驟(6)。
(8)在app.xaml代碼隱藏文件中,給OnSuspending方法設(shè)置一個(gè)斷點(diǎn)。
(9)運(yùn)行該應(yīng)用程序。
(10)一旦運(yùn)行應(yīng)用程序,就單擊一兩個(gè)頁(yè)面上的Bold按鈕。然后,應(yīng)用程序仍在運(yùn)行,返回Visual Studio。如果沒(méi)有顯示Debug Location工具欄,則在工具欄區(qū)域右擊并確保選中它。單擊Lifecycle Events下拉框,單擊Suspend。
(11)一旦單步執(zhí)行OnSuspended方法,應(yīng)用程序就暫停。再次展開(kāi)下拉框,單擊Resume。
示例說(shuō)明
AppState類使用Wmdows.Storage.ApplicationData類來(lái)保存應(yīng)用程序設(shè)置。這個(gè)類允許訪問(wèn)應(yīng)用程序數(shù)據(jù)存儲(chǔ),輕松地設(shè)置一些簡(jiǎn)單的值。應(yīng)該只在這個(gè)庫(kù)中存儲(chǔ)簡(jiǎn)單類型,如果需要保存應(yīng)用程序中非常復(fù)雜的狀態(tài), 應(yīng)該考慮其他一些機(jī)制,如數(shù)據(jù)庫(kù)或XML文件。
應(yīng)用程序己經(jīng)在app.xaml代碼隱藏代碼文件中處理了 Suspending事件,所以可以簡(jiǎn)單地使用它。如果必須為某些頁(yè)面單獨(dú)暫停事件,也應(yīng)該在頁(yè)面本身處理這個(gè)事件。
在OnSuspending事件中,保存了整個(gè)應(yīng)用程序的狀態(tài),以便在應(yīng)用程序重新啟動(dòng)時(shí)可以檢索它。由于在應(yīng)用程序從暫停中恢復(fù)時(shí),任何頁(yè)面都沒(méi)有必須要更新的數(shù)據(jù),所以沒(méi)有處理Resuming事件。
在OnLaunched方法加載應(yīng)用程序時(shí),恢復(fù)狀態(tài),OnLaunched方法也位于app.xaml代碼隱藏文件中。
點(diǎn)擊加載更多評(píng)論>>