win8開發(7)——資源限定符和資源映射


上一篇文章中,我們吹了一下資源和本地化,同時也做了一個實例,本文我們再深入探索一下資源限定符和資源路徑的映射。這兩個玩意兒也許我們在實際開發中並不十分關注,不過,瞭解一下,還是有好處的。
這兩個名詞看起來就抽象,或者,我們會感覺到,從文字描述無法理解它們,那麼,老規矩,我們還是用實驗來看看是否能將抽象的概念形象化。

1、啓動VS,新建一個Modern風格的應用程序項目(也就前面說過的板磚風格)。
2、在“解決方案資源管理器”中的項目節點上右擊,從快捷菜單中依次選擇“添加”-“新建項”,在模板列表中找到資源文件(.resw),文件名按默認Resources即可,確定。
3、在剛纔新建的資源文件中,隨便輸入一些資源,如圖:
1.png 


4、保存並關閉資源文件,另外,在項目中新建兩個空白頁面,分別爲PageQt.xaml和PageMaps.xaml,現在,你的解決方案結構應該類似下圖所示。

2.png 

(1)打開PageQt.xaml,界面佈局參考下面的XAML。
    <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">  
    <TextBlock Name="tb" FontSize="20" TextWrapping="Wrap" Margin="3"/>  
    </Grid>  

切換到PageQt.xaml.cs,C#代碼如下所示。



  • using System;
  • using System.Collections.Generic;
  • using System.IO;
  • using System.Linq;
  • using Windows.Foundation;
  • using Windows.Foundation.Collections;
  • using Windows.UI.Xaml;
  • using Windows.UI.Xaml.Controls;
  • using Windows.UI.Xaml.Controls.Primitives;
  • using Windows.UI.Xaml.Data;
  • using Windows.UI.Xaml.Input;
  • using Windows.UI.Xaml.Media;
  • using Windows.UI.Xaml.Navigation;
  • // 引入以下命名空間
  • using Windows.ApplicationModel.Resources;
  • using Windows.ApplicationModel.Resources.Core;
  • namespace MyApp
  • {
  •     /// <summary>
  •     /// 可用於自身或導航至 Frame 內部的空白頁。
  •     /// </summary>
  •     public sealed partial class PageQt : Page
  •     {
  •         public PageQt()
  •         {
  •             this.InitializeComponent();
  •             this.Loaded += PageQt_Loaded;
  •         }
  •         void PageQt_Loaded(object sender, RoutedEventArgs e)
  •         {
  •             ResourceContext context = ResourceManager.Current.DefaultContext;
  •             string resultStr = string.Empty;
  •             foreach (var item in context.QualifierValues)
  •             {
  •                 resultStr += string.Format("{0} => {1}", item.Key, item.Value);
  •                 resultStr += "\n";
  •             }
  •             this.tb.Text = resultStr;
  •         }
  •     }
  • }
(3)保存,接着打開PageMaps.xaml,XAML如下所示。


  • <Page
  •     x:Class="MyApp.PageMaps"
  •     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  •     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  •     xmlns:local="using:MyApp"
  •     xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  •     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  •     mc:Ignorable="d">
  •     <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
  •         <TextBlock Name="tb" FontSize="20" TextWrapping="Wrap" Margin="3"/>
  •     </Grid>
  • </Page>
切換到C#代碼視圖,處理代碼如下面清單所示:



  • using System;
  • using System.Collections.Generic;
  • using System.IO;
  • using System.Linq;
  • using Windows.Foundation;
  • using Windows.Foundation.Collections;
  • using Windows.UI.Xaml;
  • using Windows.UI.Xaml.Controls;
  • using Windows.UI.Xaml.Controls.Primitives;
  • using Windows.UI.Xaml.Data;
  • using Windows.UI.Xaml.Input;
  • using Windows.UI.Xaml.Media;
  • using Windows.UI.Xaml.Navigation;
  • // 引用以下命名空間
  • using Windows.ApplicationModel.Resources;
  • using Windows.ApplicationModel.Resources.Core;
  • namespace MyApp
  • {
  •     public sealed partial class PageMaps : Page
  •     {
  •         public PageMaps()
  •         {
  •             this.InitializeComponent();
  •             this.Loaded += (sender, args) =>
  •                 {
  •                     string str = "";
  •                     foreach (var item in ResourceManager.Current.AllResourceMaps)
  •                     {
  •                         str += "-------------------- " + item.Key + " --------------------\n";
  •                         foreach (var x in item.Value)
  •                         {
  •                             str += string.Format("{0} => {1}\n", x.Key, x.Value.Uri);
  •                         }
  •                         str += "\n\n";
  •                     }
  •                     this.tb.Text = str;
  •                 };
  •         }
  •     }
  • }
5、現在回到MainPage.xaml,把頁面根Grid分爲兩列,左邊放一個ListBox,右邊放一個Frame,相信你也猜到用來幹啥的,對,就是用Frame來導航顯示前面我們做的兩個頁面,一個顯示資源限定符信息,另一個顯示路徑映射。



  • <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
  •     <Grid.ColumnDefinitions>
  •         <ColumnDefinition Width="150"/>
  •         <ColumnDefinition/>
  •     </Grid.ColumnDefinitions>
  •     <ListBox Name="lb" Grid.Column="0" SelectionChanged="onSelectionChanged">
  •         <ListBoxItem>資源限定符</ListBoxItem>
  •         <ListBoxItem>資源映射</ListBoxItem>
  •     </ListBox>
  •     <Frame x:Name="frameRight" Grid.Column="1" Margin="2"/>
  • </Grid>
        [C# Code]



  • using System;
  • using System.Collections.Generic;
  • using System.IO;
  • using System.Linq;
  • using Windows.Foundation;
  • using Windows.Foundation.Collections;
  • using Windows.UI.Xaml;
  • using Windows.UI.Xaml.Controls;
  • using Windows.UI.Xaml.Controls.Primitives;
  • using Windows.UI.Xaml.Data;
  • using Windows.UI.Xaml.Input;
  • using Windows.UI.Xaml.Media;
  • using Windows.UI.Xaml.Navigation;
  • // “空白頁”項模板在http://go.microsoft.com/fwlink/?LinkId=234238上有介紹
  • namespace MyApp
  • {
  •     /// <summary>
  •     /// 可用於自身或導航至 Frame 內部的空白頁。
  •     /// </summary>
  •     public sealed partial class MainPage : Page
  •     {
  •         public MainPage()
  •         {
  •             this.InitializeComponent();
  •         }
  •         /// <summary>
  •         /// 在此頁將要在 Frame 中顯示時進行調用。
  •         /// </summary>
  •         /// <param name="e">描述如何訪問此頁的事件數據。Parameter
  •         /// 屬性通常用於配置頁。</param>
  •         protected override void OnNavigatedTo(NavigationEventArgs e)
  •         {
  •             lb.SelectedIndex = 0;
  •         }
  •         private void onSelectionChanged(object sender, SelectionChangedEventArgs e)
  •         {
  •             ListBox lb = sender as ListBox;
  •             if (lb!=null)
  •             {
  •                 int index = lb.SelectedIndex;
  •                 switch (index)
  •                 {
  •                     case 0:
  •                         this.frameRight.Navigate(typeof(PageQt));
  •                         break;
  •                     case 1:
  •                         this.frameRight.Navigate(typeof(PageMaps));
  •                         break;
  •                     default:
  •                         this.frameRight.Navigate(typeof(PageQt));
  •                         break;
  •                 }
  •             }
  •         }
  •     }
  • }
6、打開清單文件Package.appxmanifest,然後切換到“打包”選項卡,把包名改一下,改成一個好看一點,方便查看的名字。後面有用。 

現在,運行一下。

4.png 

5.png 
從第一張截圖中,我們可以大概知道什麼是資源限定符,上一篇文章中我們的例子,實現簡/繁體中文切換,我們用到了限定符中的一種——語言標記。從圖中我們看到,限定符有:
Language:當前應用首選的語言;
Contrast:對比度。
Scale:縮放比例。
HomeRegion:區域。
And so on.
如果你想了解更多有關限定符的東東,可以看看官方的文檔。
官方文檔
這東西沒什麼技巧可言,你就按照文檔說的去做就行了。

再來看看路徑映射,前面我們修改包名,就是爲了在這裏好查看,

6.png 
不知道各位在上面的截圖中發現了什麼規律?
1、資源路徑是以ms-resource:// 打頭的。
2、應用程序所認爲的資源不僅僅是.resw文件,看上圖,幾乎把我們項目中的所有文件都列出來了。
3、那麼,我們在引用某項資源時,是按key來引用的,也就是圖中“=>”左邊的內容。
4、重點關注一下Resources.resw的映射,從圖中我們看到,Resources.resw的引用名爲Resources,這個名字是默認的,還記得上一篇文章中的例子嗎?我們實例化ResourceLoader時,是調用了無參數的構造函數,那是因爲Resources是默認值,如果我們添加的資源文件是abc.resw,那麼我們在實例化ResourceLoader時,就不能用無參構造函數了,而要傳遞一個引用名,按照上面我們實驗得出的規律,引用名應當是abc。
繼續回到上圖,在Resources下的兩個資源項也被映射到不同的URI,即Resources/Key1和Resources/Key2,所以,以後要引用資源,你應該懂得怎麼做了。
ResourceMap類有個GetSubtree方法,它可以返回指定引用的子映射,比如,上圖中,如果調用GetSubtree("Resources"),這樣,返回的Map就只剩下Key1和Key2了,就是我們要找的資源項,然後在返回的ResourceMap上再調用GetValue("Key1"),就能取到資源了。

下面再做實例,看看如何從ResourceMap映射中取出資源項的值。
1、新建項目。
2、在MainPage.xaml中完成佈局。


  • <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">  
  •     <StackPanel Margin="25">  
  •         <TextBlock FontSize="20" Text="第一個值:"/>  
  •         <TextBlock FontSize="24" Name="tb1"/>  
  •          
  •         <TextBlock FontSize="20" Margin="0,20,0,0" Text="第二個值:"/>  
  •         <TextBlock FontSize="24" Name="tb2"/>  
  •     </StackPanel>  
  • </Grid>  
3、切換到C#代碼視圖。


  • protected override void OnNavigatedTo(NavigationEventArgs e)  
  • {  
  •     ResourceMap map = ResourceManager.Current.MainResourceMap.GetSubtree("Resources");  
  •     tb1.Text = map.GetValue("v1").ValueAsString;  
  •     tb2.Text = map.GetValue("v2").ValueAsString;  
  • }  

然後,運行程序,查看效果
1346818361_3602.png

3.png (9.05 KB, 下載次數: 0)

3.png

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章