在 Windows 市集應用程式中建立和擷取資源
Windows 8 作業系統引入新的 Windows 市集應用程式資源模型,取代 .NET Framework 桌面應用程式常用的中樞和支點模型。本主題將討論這個新資源模型,並說明如何建立、部署和擷取 Windows 市集應用程式的資源。
Windows 市集應用程式中的資源
.NET Framework 傳統型應用程式使用中樞和支點模型來封裝及部署資源。一般而言,應用程式中性文化特性 (此為沒有當地語系化資源時改用之資源的文化特性) 的資源會內嵌在應用程式的主要可執行檔中。每個額外文化特性的當地語系化資源內嵌在獨立的附屬組件中,這些附屬組件僅包含資源,不包含可執行的程式碼。
相較之下,Windows 市集應用程式使用單一資源檔。此檔案的名稱是封裝資源索引 (PRI) 檔,儲存所有語言、文化特性和縮放比例的相關資源。
重要
資源後援規則決定如果找不到特定文化特性或目前文化特性的當地語系化資源時,將載入哪些資源。
在傳統型應用程式中,您可以使用文字檔或 XML (.resx) 檔來建立資源。接著使用資源檔產生器 (Resgen.exe),將這些檔案編譯為二進位資源 (.resources) 檔。您可以使用編譯器,將中性文化特性的資源內嵌至主應用程式組件,並使用組件連結器 (AL.exe) 將其他所有當地語系化資源內嵌至附屬組件。接著使用 System.Resources.ResourceManager 類別擷取個別資源,或使用 ResourceReader 類別列舉資源。
在 Windows 市集應用程式中,您可以使用 .resw 檔案建立資源。雖然副檔名不同,但 .resw 檔案格式與 .resx 檔案格式相同,除了 .resw 檔案可能只包含字串和檔案路徑。您可以使用 Visual Studio 資源編輯器來建立和編輯資源。在編譯時期,應用程式的所有 .resw 檔案都由 MakePRI 公用程式封裝在單一 PRI 檔案中,隨附於應用程式的部署套件。而在執行階段,由 Windows.ApplicationModel.Resources.ResourceLoader 類別和 Windows.ApplicationModel.Resources.Core 命名空間中的型別提供對應用程式資源的存取。
重要
資源檔產生器 (Resgen.exe) 主要用於傳統型應用程式,不過您也可以使用此工具,將附屬組件反編譯為 .resw 檔案,接著再編譯為 PRI 檔案。
警告
雖然 適用於 Windows 市集應用程式的 .NET 中提供 System.Resources.ResourceManager 類別,但不建議將它用於此用途。ResourceManager 僅適用於開發為可攜式類別庫專案的程式庫,和以多個平台為目標的程式庫。
建立資源檔
Visual Studio 的資源編輯器提供建立 .resw 檔案最簡單、方便的方式。這些編輯器提供的使用者介面,會隱藏 .resw 檔案的基礎 XML 檔案格式。使用 Visual Studio 建立和編輯資源檔有兩個主要好處:
不需要手動建立資源檔,可確保其 XML 格式是有效的。
能掌握使用 MakePRI 公用程式來編譯資源、將其封裝至 PRI 檔案以及加入應用程式部署套件的整個過程。
在傳統型應用程式中,使用 NeutralResourcesLanguageAttribute 屬性來定義您的應用程式的中性文化特性。而在 Windows 市集應用程式中,當建立 PRI 檔案時,以及使用 Windows ResourceLoader 類別來擷取資源時,則忽略這個屬性。
在 Windows 市集應用程式中,透過建立資料夾來儲存所支援文化特性的資源和影像,指定當地語系化資源檔的名稱。接著可以使用文化特性名稱 (例如 "ko-kr"),後面接續預設的資源名稱和資源檔副名 (例如 "ko-kr\Resources.resw"),說明資源。
部署資源檔
若是屬於 Visual Studio 專案一部分的資源檔,Visual Studio 會處理其應用程式部署的所有細節。Visual Studio 會為屬於專案一部分的所有資源自動產生組態檔、使用 MakePRI 工具將這些資源加入單一 PRI 檔案,以及將 PRI 檔案放入應用程式的部署套件中。
由於所有資源都放在單一 PRI 檔案中 (而不是個別檔案的集合),若要修改現有的資源檔,或透過增加資源檔來新增當地語系化文化特性的支援,都需要重新建置並重新散發整個應用程式。
從資源檔擷取資源
若要擷取 Windows 市集應用程式中的資源,您必須具現化 Windows 執行階段 Windows.ApplicationModel.Resources.ResourceLoader 物件或 Windows.ApplicationModel.Resources.Core 命名空間中的其中一個型別。雖然 Windows 市集應用程式支援 .NET Framework System.Resources.ResourceManager 類別,但不建議將它用於此用途。ResourceManager僅適用於開發以多個平台為目標的可攜式類別庫專案時。下表列出 ResourceManager 成員及其在 Windows.ApplicationModel.Resources.ResourceLoader 類別或 Windows.ApplicationModel.Resources.Core 命名空間之型別中的簡單對等項目。
ResourceManager 成員 |
ResourceLoader 或其他 Windows 執行階段型別的對等成員 |
---|---|
Windows.ApplicationModel.Resources.ResourceLoader.GetString(String) |
|
Windows.ApplicationModel.Resources.Core.ResourceMap.GetValue(String, ResourceContext) |
|
ResourceManager.ResourceManager(String, Assembly) |
Windows.ApplicationModel.Resources.ResourceLoader.ResourceLoader() -或- Windows.ApplicationModel.Resources.ResourceLoader.ResourceLoader(String) |
"Hello World" 簡單範例
以下是 Windows 市集應用程式的簡單範例,會顯示當地語系化的字串。它的中性文化特性是俄文 (俄羅斯),不過它也包含英文 (美國) 和法文 (法國) 文化特性的資源。如果應用程式在目前文化特性是英文 (美國) 的系統上執行,會以英文顯示問候語,否則會顯示預設的俄文問候語。最後,不論目前的文化特性為何,都使用 Windows.ApplicationModel.Resources.Core.ResourceContext 和 Windows.ApplicationModel.Resources.Core.ResourceMap 物件顯示法文問候語。
若要將輸出顯示至 TextBlock 控制項,這個範例需要將下列 <TextBlock> 標記加入至 BlankPage.xaml:
<Grid Background="{StaticResource PageBackgroundBrush}"> <TextBlock x:Name="outputBlock" /> </Grid>
接著從 BlankPage 類別建構函式呼叫應用程式程式碼,如下所示:
Public Sub New()
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
Example.Run(outputBlock)
End Sub
public BlankPage()
{
InitializeComponent();
Example.Run(outputBlock);
}
這個範例需要您建立下列資源:
名為 "Greeting" 的俄文語言資源,其值為 "Привет!"。應在專案根層級,將此字串加入至名為 Resources.resw 的資源檔。
名為 "Greeting" 的英文語言資源,其值為 "Hi there!"。若要建立資源檔,請將名為 en-US 的資料夾加入至專案,然後將名為 Resources.resw 的資源檔加入至資料夾。
名為 "Greeting" 的法文語言資源,其值為 "Bonjour!"。若要建立資源檔,請將名為 fr-FR 的資料夾加入至專案,然後將名為 Resources.resw 的資源檔加入至資料夾。
下列範例會在 TextBlock 控制項中顯示適當的當地語系化字串。
Imports System.Globalization
Imports Windows.ApplicationModel.Resources
Imports Windows.ApplicationModel.Resources.Core
Imports Windows.UI.Xaml.Controls
Public Class Example
Public Shared Sub Run(outputBlock As Windows.UI.Xaml.Controls.TextBlock)
outputBlock.Text += String.Format("{1}The current culture is {0}.{1}",
CultureInfo.CurrentCulture.Name, vbCrLf)
Dim rl As ResourceLoader = New ResourceLoader()
' Display greeting using the resources of the current culture.
Dim greeting As String = rl.GetString("Greeting")
outputBlock.Text += String.Format("{0}{1}",
If(String.IsNullOrEmpty(greeting), "Здрауствуйте", greeting),
vbCrLf)
' Display greeting using fr-FR resources.
Dim ctx As ResourceContext = New Windows.ApplicationModel.Resources.Core.ResourceContext()
ctx.Languages = {"fr-FR"}
Dim rmap As ResourceMap = ResourceManager.Current.MainResourceMap.GetSubtree("Resources")
Dim newGreeting As String = rmap.GetValue("Greeting", ctx).ToString()
outputBlock.Text += String.Format("{1}{1}Culture of Current Context: {0}{1}",
ctx.Languages(0), vbCrLf)
outputBlock.Text += String.Format("{0}{1}", If(String.IsNullOrEmpty(newGreeting),
greeting, newGreeting), vbCrLf)
End Sub
End Class
using System;
using System.Globalization;
using Windows.ApplicationModel.Resources;
using Windows.ApplicationModel.Resources.Core;
using Windows.UI.Xaml.Controls;
public class Example
{
public static void Run(Windows.UI.Xaml.Controls.TextBlock outputBlock)
{
outputBlock.Text += String.Format("\nThe current culture is {0}.\n", CultureInfo.CurrentCulture.Name);
ResourceLoader rl = new ResourceLoader();
// Display greeting using the resources of the current culture.
string greeting = rl.GetString("Greeting");
outputBlock.Text += String.Format("{0}\n", String.IsNullOrEmpty(greeting) ? "Здрауствуйте" : greeting);
// Display greeting using fr-FR resources.
ResourceContext ctx = new Windows.ApplicationModel.Resources.Core.ResourceContext();
ctx.Languages = new string[] { "fr-FR" } ;
ResourceMap rmap = ResourceManager.Current.MainResourceMap.GetSubtree("Resources");
string newGreeting = rmap.GetValue("Greeting", ctx).ToString();
outputBlock.Text += String.Format("\n\nCulture of Current Context: {0}\n", ctx.Languages[0]);
outputBlock.Text += String.Format("{0}\n", String.IsNullOrEmpty(newGreeting) ? greeting : newGreeting);
}
}
當您編譯和執行應用程式時,它會在 en-US 文化特性的系統上顯示類似下列的輸出:
The current culture is en-US. Hi there! Culture of Current Context: fr-FR Bonjour!