老周的部落格專欄:http://blog.csdn.net/tcjiaan
轉載請註明原作者和出處。
大家可能還記得,在WP開發中,我們曾討論過應用程式狀態。同樣地,在Win8開發上,我們還可以適當地使用這玩意兒。上一節中,我們從應用程式周期中瞭解到,當我們的“板磚”應用程式不在前台運行時,就會被掛起。
而這個掛起行為其實和WP中的差不多,在WP中,其實應用程式的目前狀態並不是說每次被放置到後台就會丟失,系統為我們維護五個應用程式的狀態,一旦堆放在背景應用程式數目超過五個,那就對不起了。呵,所以,我們應考慮在適當的時候儲存應用程式狀態。
在Win8也會類似這樣的情況,不過,相對而言,沒有WP控制那麼嚴格,除非你手動把應用程式進程給幹掉或者應用程式退出。
注意哦,咱們這裡說的應用程式狀態僅僅是在運行時有效,這些資料並不是儲存到硬碟或存放裝置上,只是存在於記憶體中,作用是方便我們傳遞資料罷了。
在過去的WinForm開發或者WPF開發中,我們會考慮使用一個靜態類或在某類中聲明一些靜態欄位來儲存全域資料,即在聲明的時候加上static關鍵字。
除了這種方法,今天,我們在Win8開發中,不妨用用這個類。
啟動VS,開啟“物件瀏覽器”,我們找到CoreApplication類,它位於Windows.ApplicationModel.Core命名空間。看圖。
我在圖上標註了,藍色那圈圈,看到沒?有個靜態屬性Properties,它其實就是一個字典結構。嗯,字典結構,應該懂了,就是一key一value那種。
現在就好辦了,我們今天就是利用它來儲存一些運行時資訊,你可以把它看成是Asp.Net中的Session。
先簡單這個樣本是怎麼玩的,玩法很簡單,玩家一個,就你自己。
我們運行樣本後,在第一個頁面中分別輸入兩個值,然後把這兩個值儲存到CoreApplication.Properties字典中;
第二個頁面和第三個頁面分別取出這些值並顯示出來。
為了能實現在同一個頁面中查看多個視圖,我在首頁面中放一個Frame,再利用這個Frame來顯示其它頁面。首頁的XAML如下。
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}"> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> <ColumnDefinition/> </Grid.ColumnDefinitions> <ListBox Grid.Column="0" VerticalAlignment="Stretch" Width="200" FontSize="28" SelectionChanged="ListBox_SelectionChanged" SelectionMode="Single"> <ListBoxItem>頁面一</ListBoxItem> <ListBoxItem>頁面二</ListBoxItem> <ListBoxItem>頁面三</ListBoxItem> </ListBox> <Frame x:Name="myFrame" Grid.Column="1"/> </Grid>
背景C#代碼就是根據ListBox中選擇的頁面來導航。
private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e) { ListBoxItem item = e.AddedItems[0] as ListBoxItem; if (item != null) { string str = item.Content as string; switch (str) { case "頁面一": myFrame.Navigate(typeof(Page1)); break; case "頁面二": myFrame.Navigate(typeof(Page2)); break; case "頁面三": myFrame.Navigate(typeof(Page3)); break; default: break; } } }
下面,我們開始做第一個頁面,就是用來輸入資料並儲存狀態的。
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}"> <Grid.RowDefinitions> <RowDefinition Height="auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <TextBlock Grid.Row="0" Margin="25" Text="第一個頁面" Style="{StaticResource HeaderTextStyle}"/> <StackPanel Margin="15" Grid.Row="1"> <TextBlock Text="在本頁輸入兩個狀態值,第一個狀態在頁面二中擷取;第二個狀態值在頁面三中擷取。" Style="{StaticResource GroupHeaderTextStyle}"/> <TextBlock Text="輸入第一個狀態值:" Margin="0,13,0,0" Style="{StaticResource BodyTextStyle}"/> <TextBox Name="txt1" Margin="5,10,0,0"/> <TextBlock Text="輸入第二個狀態值:" Margin="0,18,0,0" Style="{StaticResource BodyTextStyle}"/> <TextBox Name="txt2" Margin="5,10,0,0"/> <Button Margin="12,20,0,0" Width="220" Content="儲存狀態" Click="onSave"/> </StackPanel> </Grid>
我們要處理儲存按鈕的單擊事件。
private void onSave(object sender, RoutedEventArgs e) { if (string.IsNullOrWhiteSpace(txt1.Text) || string.IsNullOrWhiteSpace(txt2.Text)) { return; } Windows.ApplicationModel.Core.CoreApplication.Properties["value1"] = txt1.Text; Windows.ApplicationModel.Core.CoreApplication.Properties["value2"] = txt2.Text; }
後面兩個頁面幾乎一樣,就是從第一個頁面儲存的狀態中讀取。
頁面二-XAML
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}"> <Grid.RowDefinitions> <RowDefinition Height="auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <TextBlock Grid.Row="0" Margin="25" Text="第二個頁面" Style="{StaticResource HeaderTextStyle}"/> <TextBlock Name="tb" FontSize="32" Margin="20,20,0,0" Grid.Row="1"/> </Grid>
頁面二-C#
protected override void OnNavigatedTo(NavigationEventArgs e) { if (Windows.ApplicationModel.Core.CoreApplication.Properties.ContainsKey("value1")) { this.tb.Text = Windows.ApplicationModel.Core.CoreApplication.Properties["value1"] as string; } }
頁面三-XAML
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}"> <Grid.RowDefinitions> <RowDefinition Height="auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <TextBlock Grid.Row="0" Margin="25" Text="第三個頁面" Style="{StaticResource HeaderTextStyle}"/> <TextBlock Name="tb" Grid.Row="1" Margin="20,20,0,0" FontSize="32"/> </Grid>
頁面三-C#
protected override void OnNavigatedTo(NavigationEventArgs e) { if (Windows.ApplicationModel.Core.CoreApplication.Properties.ContainsKey("value2")) { this.tb.Text = Windows.ApplicationModel.Core.CoreApplication.Properties["value2"] as string; } }
運行一下吧。首先,在首頁左邊的列表中選頁面一,輸入兩個資料,記得點儲存按鈕。
接著分別轉到頁面二和頁面三,看看頁面中顯示了結果沒?
這個簡單吧?當然,在測試中我們也發現了,當掛起後再回到程式,文字框中輸入的內容不見了,但已經儲存到CoreApplication.Properties到中的內容仍然可以讀取。
當然了,如果你把應用程式退出了,自然儲存的狀態也會丟失。因此,如果在程式掛起後保留文字框中的資料,各位應該知道怎麼做了。
如果要在程式退出後,在下次運行時還能讀取配置資訊,那麼就需要把資料儲存到硬碟中了,這個嘛,下一篇文章再研究吧。
下面我們說說與運行時狀態有關的另一個東東——頁面參數傳遞。
各位一看到這個,一定會想起在WP中的頁面傳參數,而且那時候,我們還說了URI映射,記得否?忘了也關係,因為我們今天用不著URI映射。
在Win8“板磚”應用開發中,頁面參數遞參數是通過調用Frame類的Navigate方法,它有兩個重載,其中一個是可以傳參數的,即
public bool Navigate(System.Type sourcePageType, object parameter)
看這參數是Object類型的,這就讓我們有了很大的發展空,我們可以傳字串,數值等,可以想多傳一些資料,可以定義一個類,直接傳遞類執行個體也行。
廢話少講,我們來做個練習就懂了。
1、啟動可愛的VS,新項目一個Windows Store應用,就是Win8應用了。
2、建立項目後,你會看到,預設開啟了App.xaml.cs檔案。
3、添加一個類,隨你喜歡,反正有公用屬性就行了。
public class Product { public string ProductName { get; set; } public string ProductID { get; set; } }
4、建立一個頁面,命名為PageGet.xaml,名字你喜歡,自己記住就行了。
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}"> <StackPanel Margin="30"> <TextBlock Text="通過頁面傳遞的參數:" Style="{StaticResource HeaderTextStyle}"/> <StackPanel Orientation="Horizontal" Margin="5,80,0,10"> <TextBlock Text="產品編號:" FontSize="28"/> <TextBlock Name="tbProID" FontSize="28"/> </StackPanel> <StackPanel Orientation="Horizontal" Margin="5,13,0,0"> <TextBlock Text="產品名稱:" FontSize="28"/> <TextBlock Name="tbProName" FontSize="28"/> </StackPanel> </StackPanel> </Grid>
在XAML文檔中右擊,從菜單中選擇“查看代碼”。
protected override void OnNavigatedTo(NavigationEventArgs e) { // 擷取參數 Product product = e.Parameter as Product; if (product != null) { this.tbProID.Text = product.ProductID; this.tbProName.Text = product.ProductName; } }
5、回過頭,開啟MainPage.xaml,我們來布局一下。
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}"> <StackPanel Margin="30"> <TextBlock Text="輸入產品編號:" Style="{StaticResource SubheaderTextStyle}"/> <TextBox Name="txtID" Margin="5,10,5,0"/> <TextBlock Margin="0,20,0,0" Text="輸入產品名稱:" Style="{StaticResource SubheaderTextStyle}"/> <TextBox Name="txtName" Margin="5,10,5,0"/> <Button Content="跳轉" Padding="35,10,35,10" Margin="15,20,0,0" Click="onNav"/> </StackPanel> </Grid>
處理按鈕的單擊事件。
private void onNav(object sender, RoutedEventArgs e) { // 取出當前視窗的根Frame if (Window.Current.Content is Frame && Window.Current.Content != null) { Frame myFrame = Window.Current.Content as Frame; Product prd = new Product() { ProductID = txtID.Text, ProductName = txtName.Text }; // 導航到目標頁面並傳遞參數 myFrame.Navigate(typeof(PageGet), prd); } }
現在,我們運行一下。