WPF 全球化和當地語系化概觀
當您限制只有一種語言可以使用您的產品時,就是將潛在客戶群限制為全世界 75 億人口的一小部分。 如果您想要全球對象都可以使用應用程式,則具成本效益的產品當地語系化是更多客戶可以使用的一種最佳且最經濟的方法。
本概觀介紹 Windows Presentation Foundation (WPF) 中的全球化和當地語系化。 全球化是在多個位置執行之應用程式的設計和開發。 例如,全球化支援不同文化特性中使用者的當地語系化使用者介面和地區資料。 WPF 提供全球化設計功能,包括自動版面配置、附屬組件,以及當地語系化屬性和註解。
當地語系化會將應用程式資源翻譯為應用程式所支援之特定文化特性的當地語系化版本。 在 WPF 中當地語系化時,請使用 System.Windows.Markup.Localizer 命名空間中的 API。 這些 API 可增強 LocBaml 工具範例命令列工具。 如需如何建置和使用 LocBaml 的資訊,請參閱將應用程式當地語系化。
警告
LocBaml 工具僅適用於 .NET Framework 專案的 WPF,不適用於適用於 .NET 的 WPF。
WPF 中的全球化和當地語系化最佳做法
您可以遵循本節所提供的 UI 設計和當地語系化相關祕訣,來善加利用 WPF 內建的全球化和當地語系化功能。
WPF UI 設計最佳做法
當您設計 WPF 型 UI 時,請考慮實作下列最佳做法:
在 XAML 撰寫 UI;避免在程式碼中建立 UI。 當您使用 XAML 建立 UI 時,請透過內建當地語系化 API 將它公開。
請避免使用絕對位置和固定大小來配置內容;相反地,請使用相對或自動調整大小。
使用 SizeToContent ,並將寬度和高度設定為
Auto
。避免使用 Canvas 來配置 UI。
使用 Grid 及其大小共用功能。
因為當地語系化文字通常需要更多空間,所以請在邊界提供額外空間。 額外空間可放置可能突出的字元。
在 TextBlock 上啟用 TextWrapping 以避免裁剪。
設定
xml:lang
屬性。 此屬性描述特定項目的文化特性和其子項目。 此屬性的值會變更 WPF 中數項功能的行為。 例如,它會變更斷字、拼字檢查、數字替代、複雜指令碼形成和字型遞補的行為。 如需設定 XAML 中的 xml:lang 處理的詳細資訊,請參閱 WPF 的全球化。建立自訂的複合字型,進一步控制用於不同語言的字型。 WPF 預設會使用 Windows\Fonts 目錄中的 GlobalUserInterface.composite 字型。
當您建立可能以從右至左格式呈現文字之文化特性的導覽應用程式時,請明確設定每個頁面的 FlowDirection ,以確保頁面不會從 NavigationWindow 繼承 FlowDirection。
當您建立裝載於瀏覽器外部的獨立導覽應用程式時,請將初始應用程式的 StartupUri 設定為 NavigationWindow,而不是頁面 (例如,
<Application StartupUri="NavigationWindow.xaml">
)。 此設計可讓您變更 Window 和導覽列的 FlowDirection。 如需詳細資訊和範例,請參閱 Globalization Homepage Sample (全球化首頁範例)。
WPF 當地語系化最佳做法
在當地語系化 WPF 型應用程式時,請考慮實作這些最佳做法:
使用當地語系化註解來提供當地語系化人員的額外內容。
使用當地語系化屬性來控制當地語系化,而不是選擇性省略元素上的 Uid 屬性。 如需詳細資訊,請參閱當地語系化屬性和註解。
使用
msbuild -t:updateuid
和-t:checkuid
,在 XAML 中新增和檢查 Uid 屬性。 使用 Uid 屬性來追蹤開發和當地語系化之間的變更。 Uid 屬性可協助您當地語系化新的開發變更。 如果您手動將 Uid 屬性新增至 UI,則工作通常很乏味且較不精確。在您開始當地語系化之後,請勿編輯或變更 Uid 屬性。
請勿使用重複 Uid 屬性 (當您使用複製和貼上命令時,請記住這個提示)。
在 AssemblyInfo.* 中設定
UltimateResourceFallback
位置,以指定適當的語言進行遞補 (例如,[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
)。如果您決定省略專案檔中的
<UICulture>
標記以將來源語言包含在主要組件中,請將UltimateResourceFallback
位置設定為主要組件,而非附屬組件 (例如,[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.MainAssembly)]
)。
將 WPF 應用程式當地語系化
當地語系化 WPF 應用程式時,有幾個選項。 例如,您可以將應用程式中的可當地語系化資源繫結至 XML 檔案、將可當地語系化文字儲存至 resx 資料表,或讓當地語系化人員使用 XAML 檔案。 本節描述使用 BAML 形式之 XAML 的當地語系化工作流程,這提供多項優點:
建置之後,即可進行當地語系化。
您可以使用當地語系化從 BAML 形式之 XAML 的舊版本更新為 BAML 形式之 XAML 的新版本,以在開發的同時進行當地語系化。
您可以在編譯期間驗證原始來源項目和語意,因為 BAML 形式的 XAML 是 XAML 的已編譯形式。
當地語系化建置程序
當您開發 WPF 應用程式時,當地語系化建置程序如下:
開發人員會建立和全球化 WPF 應用程式。 在專案檔中,開發人員設定
<UICulture>en-US</UICulture>
,因此,編譯應用程式時,會產生語言中性主要組件。 此組件具有包含所有可當地語系化資源的附屬 .resources.dll 檔案。 您可以選擇性保持主要組件中的來源語言,因為我們的當地語系化 API 支援從主要組件進行擷取。將檔案編譯為組建時,會將 XAML 轉換為 BAML 形式的 XAML。 與文化特性無關的
MyDialog.exe
以及與文化特性有關的 (英文)MyDialog.resources.dll
檔案都會發行給英語系的客戶。
當地語系化工作流程
當地語系化程序會在建置未當地語系化 MyDialog.resources.dll
檔案之後開始。 原始 XAML 中的 UI 元素和屬性會從 BAML 形式之 XAML擷取鍵值組,方法是使用 System.Windows.Markup.Localizer 下的 API。 當地語系化人員會使用鍵值組來當地語系化應用程式。 當地語系化完成之後,即可從新值產生新的 .resource.dll。
鍵值組的索引鍵是開發人員在原始 XAML 中所放置的 x:Uid
值。 這些 x:Uid
值可讓 API 追蹤和合併當地語系化期間開發人員與當地語系化人員之間所發生的變更。 例如,如果開發人員在當地語系化人員開始當地語系化之後變更 UI,則您可以合併開發變更與已完成的當地語系化工作,這樣遺失的翻譯工作最少。
下圖顯示根據 BAML 形式之 XAML 的一般當地語系化工作流程。 本圖假設開發人員是以英文來撰寫應用程式。 開發人員會建立和全球化 WPF 應用程式。 在專案檔中,開發人員會設定 <UICulture>en-US</UICulture>
,因此,建置時,會使用包含所有可當地語系化資源的附屬 .resources.dll 來產生語言中性主要組件。 或者,有人保持主要組件中的來源語言,因為 WPF 當地語系化 API 支援從主要組件進行擷取。 建置程序之後,XAML 會編譯到 BAML。 與文化特性無關的 MyDialog.exe.resources.dll 會傳送給英語系的客戶。
WPF 當地語系化範例
本節包含當地語系化應用程式的範例,協助您了解如何建置和當地語系化 WPF 應用程式。
執行對話方塊範例
下圖顯示 [執行] 對話方塊範例的輸出。
英文:
德文:
設計全域執行對話方塊
此範例會使用 WPF 和 XAML 產生 執行 對話方塊。 此對話方塊相當於 Microsoft Windows [開始] 功能表提供的 [執行] 對話方塊。
建立全域對話方塊的一些重點如下︰
自動版面配置
在 Window1.xaml 中:
<Window SizeToContent="WidthAndHeight">
前一個 Window 屬性會根據內容的大小來自動調整視窗大小。 此屬性會防止視窗中在當地語系化因大小增加而裁切內容;內容在當地語系化後大小減少時,它也會移除不必要的空間。
<Grid x:Uid="Grid_1">
需要 Uid 屬性,WPF 當地語系化 API 才能正常運作。
WPF 當地語系化 API 會使用它們來追蹤使用者介面 (UI) 開發和當地語系化之間的變更。 Uid 屬性可讓您將較新版本的 UI 與舊版 UI 當地語系化合併。 您可以在命令殼層中執行 msbuild -t:updateuid RunDialog.csproj
,以新增 Uid 屬性。 這是新增 Uid 屬性的建議方法,因為手動新增屬性通常是耗時且較不精確的。 您可以執行 msbuild -t:checkuid RunDialog.csproj
,檢查是否已正確設定 Uid 屬性。
UI 是使用 Grid 控制項進行結構化,這是利用 WPF 中自動版面配置的實用控制項。 請注意,對話方塊分成三個資料列和五個資料行。 沒有一個資料列和資料行定義具有固定大小;因此,位於每個儲存格中的 UI 項目可以在當地語系化期間隨著大小增加和減少進行調整。
<Grid.ColumnDefinitions>
<ColumnDefinition x:Uid="ColumnDefinition_1" />
<ColumnDefinition x:Uid="ColumnDefinition_2" />
前兩個資料行放置 Open: 標籤和 ComboBox,會使用 10% 的 UI 總寬度。
<ColumnDefinition x:Uid="ColumnDefinition_3" SharedSizeGroup="Buttons" />
<ColumnDefinition x:Uid="ColumnDefinition_4" SharedSizeGroup="Buttons" />
<ColumnDefinition x:Uid="ColumnDefinition_5" SharedSizeGroup="Buttons" />
</Grid.ColumnDefinitions>
請注意,此範例使用 Grid 的共用調整大小功能。 最後三個資料行會將自己放在相同的 SharedSizeGroup,藉此利用這個功能。 因為其中一個預期來自屬性名稱,所以這可讓資料行共用相同的大小。 所以,"Browse…" 當地語系化為較長的字串 "Durchsuchen…",則所有按鈕的寬度都會增加,而不會有較小的 "OK" 按鈕,以及顯得特別大的 "Durchsuchen…" 按鈕。
xml:lang
xml:lang="en-US"
請注意放在 UI 根項目處之 XAML 中的 xml:lang 處理。 此屬性描述所指定項目的文化特性和其子項目。 此值是供 WPF 中的數個功能使用,而且應該在當地語系化期間適當地變更。 此值可變更使用何種語言字典來進行斷字和拼字檢查。 它也會影響顯示的位數,以及字型遞補系統如何選取要使用的字型。 最後,此屬性會影響數字顯示方式,以及使用複雜指令碼所撰寫之文字的形成方式。 預設值是 "en-US"。
建置附屬資源組件
在 .csproj 中:
編輯 .csproj
檔案,並將下列標籤新增至無條件 <PropertyGroup>
:
<UICulture>en-US</UICulture>
請注意已新增 UICulture
值。 當此值設定為有效的 CultureInfo 值,例如 en-US 時,建置專案會在其中產生具有所有可當地語系化資源的附屬組件。
<Resource Include="RunIcon.JPG">
<Localizable>False</Localizable>
</Resource>
RunIcon.JPG
不需要進行當地語系化,因為它在所有文化特性中的外觀都應該相同。 Localizable
設定為 false
,因此,它仍然存在於語言中性主要組件中,而非附屬組件中。 所有無法編譯資源的預設值都是設定為 true
的 Localizable
。
將執行對話方塊當地語系化
剖析
建置應用程式之後,將它當地語系化的第一個步驟是剖析附屬組件的可當地語系化資源。 基於本主題的目的,請使用 LocBaml 工具範例中提供的 LocBaml 範例工具。 請注意,LocBaml 只是一種範例工具,旨在協助您開始建置符合當地語系化程序的當地語系化工具。 使用 LocBaml,執行下列命令來進行剖析︰LocBaml /parse RunDialog.resources.dll /out: 以產生 "RunDialog.resources.dll.CSV" 檔案。
警告
LocBaml 工具僅適用於 .NET Framework 專案的 WPF,不適用於適用於 .NET 的 WPF。
當地語系化
使用支援 Unicode 的慣用 CSV 編輯器,才能編輯這個檔案。 篩選出當地語系化分類為 "None" 的所有項目。 您應該會看到下列項目:
資源索引鍵 | 當地語系化分類 | 值 |
---|---|---|
Button_1:System.Windows.Controls.Button.$Content | Button | 確定 |
Button_2:System.Windows.Controls.Button.$Content | Button | 取消 |
Button_3:System.Windows.Controls.Button.$Content | Button | 瀏覽... |
ComboBox_1:System.Windows.Controls.ComboBox.$Content | ComboBox | |
TextBlock_1:System.Windows.Controls.TextBlock.$Content | Text | 輸入程式、資料夾、文件或網際網路資源的名稱,Windows 會自動開啟。 |
TextBlock_2:System.Windows.Controls.TextBlock.$Content | Text | 開啟: |
Window_1:System.Windows.Window.Title | 標題 | 執行 |
將應用程式當地語系化為德文需要下列翻譯︰
資源索引鍵 | 當地語系化分類 | 值 |
---|---|---|
Button_1:System.Windows.Controls.Button.$Content | Button | 確定 |
Button_2:System.Windows.Controls.Button.$Content | Button | Abbrechen |
Button_3:System.Windows.Controls.Button.$Content | Button | Durchsuchen… |
ComboBox_1:System.Windows.Controls.ComboBox.$Content | ComboBox | |
TextBlock_1:System.Windows.Controls.TextBlock.$Content | Text | Geben Sie den Namen eines Programms, Ordners, Dokuments oder einer Internetresource an. |
TextBlock_2:System.Windows.Controls.TextBlock.$Content | Text | 開啟: |
Window_1:System.Windows.Window.Title | 標題 | 執行 |
產生
當地語系化的最後一個步驟包括建立新的當地語系化附屬組件。 使用下列 LocBaml 命令,即可完成這項作業:
LocBaml.exe /generate RunDialog.resources.dll /trans:RunDialog.resources.dll.CSV /out: . /cul:de-DE
在德文 Windows 上,如果此 resources.dll 放在主要組件旁邊的 de-DE 資料夾中,則會自動載入此資源,而非 en-US 資料夾中的 resources.dll。 如果您沒有德文版本的 Windows 進行測試,請將文化特性設定為您使用的任何 Windows 文化特性 (例如,en-US
),並取代原始資源 DLL。
附屬資源載入
MyDialog.exe | en-US\MyDialog.resources.dll | de-DE\MyDialog.resources.dll |
---|---|---|
代碼 | 附屬資源 BAML | 當地語系化 BAML |
文化特性中性資源 | 英文的其他資源 | 當地語系化為德文的其他資源 |
.NET 會根據應用程式的 Thread.CurrentUICulture 來自動選擇要載入的附屬資源組件。 這會預設為 Windows OS 的文化特性。 如果您使用德文 Windows,de-DE\MyDialog.resources.dll 檔案會載入。 如果您使用英文 Windows, en-US\MyDialog.resources.dll 檔案會載入。 您可以在專案的 AssemblyInfo 檔案中指定 NeutralResourcesLanguage
屬性,以設定應用程式的最終後援資源。 例如,如果您指定:
[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
然後,如果下列兩個檔案都無法使用:de-DE\MyDialog.resources.dll 或 de\MyDialog.resources.dll, 則 en-US\MyDialog.resources.dll 檔案會與德文 Windows 搭配使用。
Microsoft Saudi Arabia 首頁
下圖顯示英文和阿拉伯文首頁。 如需詳細資訊和範例,請參閱 Globalization Homepage Sample (全球化首頁範例)。
英文:
阿拉伯文:
設計全域 Microsoft 首頁
這個模擬的 Microsoft Saudi Arabia 網站說明針對 RightToLeft 語言所提供的全球化功能。 希伯來文和阿拉伯文這類語言的閱讀順序都是由右至左,因此 UI 版面配置的配置方式會與英文這類由左至右的語言相當不同。 從由左至右語言當地語系化為由右至左語言 (反之亦然) 可能相當困難。 WPF 設計成讓這類當地語系化更為簡單。
FlowDirection
Homepage.xaml:
<Page x:Uid="Page_1" x:Class="MicrosoftSaudiArabiaHomepage.Homepage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
FlowDirection="LeftToRight"
Localization.Comments="FlowDirection(This FlowDirection controls the actual content of the homepage)"
xml:lang="en-US">
請注意在 Page 的 FlowDirection 屬性。 將此屬性變更為 RightToLeft 時會變更 Page 及其子系元素的 FlowDirection ,如此一來,此 UI 的版面配置就會變成由右至左,如同阿拉伯使用者預期的那樣。 您可以在任何元素上指定明確的 FlowDirection ,以覆寫繼承行為。 FlowDirection 屬性可在任何 FrameworkElement 或文件相關元素上使用,且具有隱含值 LeftToRight。
請注意,當根 FlowDirection 變更時,即使是背景漸層筆刷也會正確翻轉:
FlowDirection="LeftToRight"
FlowDirection="RightToLeft"
避免面板和控制項使用固定維度
查看 Homepage.xaml,請注意,除了為上方 DockPanel 上整個 UI 指定的固定寬度和高度之外,沒有其他固定尺寸。 請避免使用固定維度,防止裁剪長度超過來源文字的當地語系化文字。 WPF 面板和控制項將會根據所含的內容來自動調整大小。 大部分控制項也有您可針對更多控制項設定的最小和最大維度 (例如,MinWidth= "20")。 使用 Grid,您也可以使用 '*' 來設定相對寬度和高度 (例如,Width="0.25*"
),或使用其儲存格大小共用功能。
當地語系化註解
在許多情況下,內容可能會模稜兩可,而不容易翻譯。 開發人員或設計人員可以透過當地語系化註解來提供額外內容和註解。 例如,下面的 Localization.Comments 釐清字元 '|' 的使用。
<TextBlock
x:Uid="TextBlock_2"
DockPanel.Dock="Right"
Foreground="White"
Margin="5,0,5,0"
Localization.Comments="$Content(This character is used as a decorative rule.)">
|
</TextBlock>
本註解會與 TextBlock_1 的內容建立關聯;而且,如果是 LocBaml 工具 (請參閱將應用程式當地語系化),則可以在輸出 .csv 檔案中 TextBlock_1 資料列的第 6 個資料行看到它:
資源索引鍵 | 類別 | 可讀取 | 可修改 | 註解 | 值 |
---|---|---|---|---|---|
TextBlock_1:System.Windows.Controls.TextBlock.$Content | Text | TRUE | TRUE | 此字元是當成裝飾規則使用。 | | |
使用下列語法,可以放入任何項目之內容或屬性的註解︰
<TextBlock
x:Uid="TextBlock_1"
DockPanel.Dock="Right"
Foreground="White"
Margin="5,0,5,0"
Localization.Comments="$Content(This is a comment on the TextBlock's content.)
Margin(This is a comment on the TextBlock's Margin property.)">
|
</TextBlock>
當地語系化屬性
開發人員或當地語系化管理員通常需要控制當地語系化人員可以讀取和修改的內容。 例如,您可能不想要當地語系化人員翻譯公司名稱或法律用語。 WPF 提供屬性,可讓您設定項目內容或屬性的可讀性、可修改性和分類,而當地語系化工具可以使用此內容或屬性來鎖定、隱藏或排序項目。 如需詳細資訊,請參閱Attributes。 基於此範例的目的,LocBaml 工具只會輸出這些屬性的值。 WPF 控制項都會有這些屬性的預設值,但您可以覆寫它們。 例如,下列範例覆寫 TextBlock_1
的預設當地語系化屬性,以及設定當地語系化人員可讀取但無法修改的內容。
<TextBlock
x:Uid="TextBlock_1"
Localization.Attributes=
"$Content(Readable Unmodifiable)">
Microsoft Corporation
</TextBlock>
除了可讀性和可修改性屬性之外,WPF 還提供通用 UI 類別的列舉 (LocalizationCategory),可用來提供當地語系化人員更多內容。 也可以覆寫 XAML 中平台控制項的 WPF 預設分類:
<TextBlock x:Uid="TextBlock_2">
<TextBlock.ToolTip>
<TextBlock
x:Uid="TextBlock_3"
Localization.Attributes=
"$Content(ToolTip Readable Unmodifiable)">
Microsoft Corporation
</TextBlock>
</TextBlock.ToolTip>
Windows Vista
</TextBlock>
WPF 所提供的預設當地語系化屬性也可以透過程式碼進行覆寫,因此,您可以正確地設定自訂控制項的正確預設值。 例如:
[Localizability(Readability = Readability.Readable, Modifiability=Modifiability.Unmodifiable, LocalizationCategory.None)]
public class CorporateLogo : TextBlock
{
// ...
}
XAML 中設定的每個執行個體屬性,其優先順序高於自訂控制項上使用程式碼所設定的值。 如需屬性和註解的詳細資訊,請參閱當地語系化屬性和註解。
字型遞補和複合字型
如果您指定的字型不支援指定的字碼指標範圍,則 WPF 會自動遞補到使用 Windows\Fonts 目錄中的 Global User Interface.compositefont 所支援的字碼指標。 複合字型的運作方式就像任何其他字型一樣,而且可以藉由設定元素的 FontFamily
來明確使用 (例如,FontFamily="Global User Interface"
)。 建立您自己的複合字型並指定要用於特定字碼指標範圍和語言的字型,即可指定自己的字型遞補喜好設定。
如需複合字型的詳細資訊,請參閱 FontFamily。
將 Microsoft 首頁當地語系化
您可以遵循「執行對話方塊」範例中的相同步驟,將此應用程式當地語系化。 Globalization Homepage Sample (全球化首頁範例) 中提供阿拉伯文的當地語系化 .csv 檔案。