上一篇文章中,我們吹了一下資源和本地化,同時也做了一個實例,本文我們再深入探索一下資源限定符和資源路徑的映射。這兩個玩意兒也許我們在實際開發中並不十分關注,不過,瞭解一下,還是有好處的。
這兩個名詞看起來就抽象,或者,我們會感覺到,從文字描述無法理解它們,那麼,老規矩,我們還是用實驗來看看是否能將抽象的概念形象化。
1、啓動VS,新建一個Modern風格的應用程序項目(也就前面說過的板磚風格)。
2、在“解決方案資源管理器”中的項目節點上右擊,從快捷菜單中依次選擇“添加”-“新建項”,在模板列表中找到資源文件(.resw),文件名按默認Resources即可,確定。
3、在剛纔新建的資源文件中,隨便輸入一些資源,如圖:
4、保存並關閉資源文件,另外,在項目中新建兩個空白頁面,分別爲PageQt.xaml和PageMaps.xaml,現在,你的解決方案結構應該類似下圖所示。
(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,然後切換到“打包”選項卡,把包名改一下,改成一個好看一點,方便查看的名字。後面有用。
現在,運行一下。
從第一張截圖中,我們可以大概知道什麼是資源限定符,上一篇文章中我們的例子,實現簡/繁體中文切換,我們用到了限定符中的一種——語言標記。從圖中我們看到,限定符有:
Language:當前應用首選的語言;
Contrast:對比度。
Scale:縮放比例。
HomeRegion:區域。
And so on.
如果你想了解更多有關限定符的東東,可以看看官方的文檔。
官方文檔
這東西沒什麼技巧可言,你就按照文檔說的去做就行了。
再來看看路徑映射,前面我們修改包名,就是爲了在這裏好查看,
不知道各位在上面的截圖中發現了什麼規律?
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;
-
}
然後,運行程序,查看效果
|