WPF のグローバリゼーションおよびローカリゼーションの概要

製品を 1 言語だけで作成することは、潜在的な顧客ベースを、65 億の世界人口のごく一部に制限することを意味します。アプリケーション製品をグローバルな市場に届けようとする場合、最良かつ経済的な方法の 1 つは、費用対効果の高いローカリゼーションです。

ここでは、Windows Presentation Foundation (WPF) のグローバリゼーションとローカリゼーションについて説明します。グローバリゼーションとは、複数の地域で実行するアプリケーションの設計と開発です。たとえば、グローバリゼーションでは、さまざまなカルチャ内のユーザー用にローカライズされたユーザー インターフェイスと地域のデータをサポートします。WPF には、自動レイアウト、サテライト アセンブリ、ローカリゼーション属性とコメントなどの、グローバル化されたデザイン機能が用意されています。

ローカリゼーションとは、アプリケーションでサポートする特定のカルチャ用のローカライズ バージョンに、アプリケーション リソースを変換することです。WPF でローカリゼーションを行う場合、System.Windows.Markup.Localizer 名前空間の API を使用します。これらの API により、LocBaml ツールのサンプル コマンド ライン ツールが機能します。LocBaml を構築して使用する方法については、「方法 : アプリケーションをローカライズする」を参照してください。

このトピックには次のセクションが含まれています。

  • WPF のグローバリゼーションとローカリゼーションのベスト プラクティス
  • WPF アプリケーションをローカライズする
  • WPF のローカリゼーションの例

WPF のグローバリゼーションとローカリゼーションのベスト プラクティス

ここに示す UI 設計とローカリゼーションに関するヒントに従うと、WPF に組み込まれたグローバリゼーション機能とローカリゼーション機能を最大限に活用できます。

WPF の UI 設計のベスト プラクティス

WPF ベースの UI を設計する場合、これらのベスト プラクティスの実装を考慮してください。

  • UI を XAML で記述します。UI はコードで作成しないようにします。XAML を使用して UI を作成する場合は、組み込みローカリゼーション API を通じて公開します。

  • コンテンツのレイアウト時に、絶対位置と固定サイズを使用しないようにします。代わりに、相対位置と自動サイズ設定を使用します。

    • SizeToContent を使用し、幅と高さの設定を Auto に維持します。

    • UI のレイアウト時に、Canvas を使用しないようにします。

    • Grid とそのサイズ共有機能を使用します。

  • ローカライズされたテキストはより多くのスペースを必要とすることが多いため、余白にスペースを確保しておきます。余分なスペースがあれば、文字の張り出しに対応できます。

  • TextBlockTextWrapping を有効にして、クリッピングを回避します。

  • xml:lang 属性を設定します。この属性は、特定の要素のカルチャと、その子要素について記述します。このプロパティの値は、WPF のいくつかの機能の動作を変更します。たとえば、ハイフネーション、スペル チェック、数字の置換、複雑な文字の整形、フォントの代替などの動作を変更します。XAML における xml:lang の処理 の設定の詳細については、「Windows Presentation Foundation のグローバリゼーション」を参照してください。

  • さまざまな言語で使用されるフォントをより良く制御するには、カスタマイズした複合フォントを作成します。既定では、WPF によって Windows\Fonts ディレクトリの GlobalUserInterface.CompositeFont が使用されます。

  • 作成するナビゲーション アプリケーションが、右から左の方向にテキストを表示するカルチャにローカライズされる可能性がある場合は、各ページの FlowDirection を明示的に設定して、ページが NavigationWindowFlowDirection を継承しないようにします。

  • ブラウザの外でホストされるスタンドアロンのナビゲーション アプリケーションを作成する場合、初期アプリケーションの StartupUri に、ページ (<Application StartupUri="NavigationWindow.xaml"> など) ではなく NavigationWindow を設定します。この設計を使用すると、ウィンドウとナビゲーション バーの FlowDirection を変更できます。詳細および例については、「グローバリゼーション ホームページのサンプル」を参照してください。

WPF のローカリゼーションのベスト プラクティス

WPF ベースのアプリケーションをローカライズする場合、次のベスト プラクティスの実装を考慮してください。

  • ローカリゼーション コメントを使用して、ローカライザに追加のコンテキストを提供します。

  • ローカリゼーションを制御するには、要素の Uid プロパティを選択的に省略するのではなく、ローカリゼーション属性を使用します。詳細については、「ローカリゼーション属性とコメント」を参照してください。

  • Uid プロパティを XAML に追加して確認するには、msbuild /t:updateuid および /t:checkuid を使用します。開発とローカリゼーション間の変更を追跡するには、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 テーブルに格納したり、ローカライザが Extensible Application Markup Language (XAML) ファイルを使用したりできます。ここでは、バイナリ XAML (BAML) を使用したローカリゼーション ワークフローについて説明します。これによって次のような利点が提供されます。

  • ビルド後にローカライズできます。

  • 古いバージョンの BAML を使用したローカリゼーションで、新しいバージョンの BAML に更新できるため、開発と同時にローカライズできます。

  • BAML は XAML をコンパイルした形式であるため、元のソース要素とセマンティクスをコンパイル時に検証できます。

ローカリゼーションのビルド プロセス

WPF アプリケーションを開発する場合の、ローカリゼーションのビルド プロセスは次のとおりです。

  • 開発者が WPF アプリケーションを作成し、グローバル化します。アプリケーションのコンパイル時に、言語に依存しないメイン アセンブリが生成されるように、プロジェクト ファイルで開発者が <UICulture>en-US</UICulture> を設定します。このアセンブリには、すべてのローカライズ可能リソースが含まれた、サテライトの .resources.dll ファイルがあります。ローカリゼーション API ではメイン アセンブリからの抽出がサポートされるため、必要に応じてソース言語をメイン アセンブリ内に残すこともできます。

  • ファイルをビルドにコンパイルすると、XAML が BAML に変換されます。カルチャに依存しない MyDialog.exe ファイルと、カルチャに依存する (英語の) MyDialog.resources.dll ファイルを、英語圏の顧客にリリースします。

ローカリゼーション ワークフロー

ローカライズされていない MyDialog.resources.dll ファイルがビルドされた後、ローカリゼーション プロセスが始まります。System.Windows.Markup.Localizer の下の API が使用され、元の XAML 内の UI 要素とプロパティが、BAML からキーと値のペアとして抽出されます。ローカライザは、キーと値のペアを使用して、アプリケーションをローカライズします。ローカリゼーションの完了後、新しい値から新しい .resource.dll を生成できます。

キーと値のペアにおけるキーは、開発者が元の XAML に配置した x:Uid です。これらの x:Uid を使用すると、ローカリゼーション時に開発者とローカライザの間で発生する変更を、API で追跡およびマージすることができます。たとえば、ローカライザがローカライズを開始した後に開発者が UI を変更した場合、完了したローカリゼーション作業に開発の変更をマージして、失われる変換作業を最小限に抑えることができます。

次の図に、BAML に基づく一般的なローカリゼーション ワークフローを示します。この図では、開発者が英語のアプリケーションを作成しているものとします。

Localization workflow

WPF のローカリゼーションの例

ここでは、WPF アプリケーションをビルドおよびローカライズする方法の理解に役立つ、ローカライズされたアプリケーションの例を示します。

[Run] ダイアログ ボックスの例

次の図は、[Run] ダイアログ ボックスのサンプルの出力を示します。

英語 :

Run dialog box

ドイツ語 :

German Run dialog box

グローバルな [Run] ダイアログ ボックスの設計

この例では、WPF および XAML を使用して、[Run] ダイアログ ボックスを作成します。このダイアログ ボックスは、Microsoft Windows の [Start] メニューから使用可能な [Run] ダイアログ ボックスと同じものです。

サンプル全体については、「グローバリゼーション実行ダイアログ ボックスのサンプル」を参照してください。

グローバルなダイアログ ボックスを作成するためのいくつかの要点を次に示します。

自動レイアウト

次の Window1.xaml の行を見てください**。

<Window SizeToContent="WidthAndHeight">

上記のウィンドウのプロパティでは、ウィンドウのサイズがコンテンツのサイズに合わせて自動的に変更されます。このプロパティは、ローカリゼーション後にサイズが大きくなるコンテンツが切り捨てられないようにします。また、ローカリゼーション後にコンテンツのサイズが小さくなる場合は、不要なスペースを削除します。

<Grid x:Uid="Grid_1">

WPF ローカリゼーションの API が正しく機能するためには、Uid プロパティが必要です。

これは、WPF ローカリゼーションの API によって、ユーザー インターフェイス (UI).の開発とローカリゼーション間の変更を追跡するために使用されます。Uid プロパティを使用すると、UI の新しいバージョンを UI の古いローカリゼーションにマージできます。Uid プロパティを追加するには、Windows SDK コマンド シェルで msbuild /t:updateuid RunDialog.csproj を実行します。Uid プロパティの追加には、この方法をお勧めします。一般に、手動で追加すると時間がかかり、正確さにも欠けます。Uid プロパティが正しく設定されたことを確認するには、msbuild /t:checkuid RunDialog.csproj を実行します。

UI は Grid コントロールを使用して構造化されます。このコントロールは、WPF の自動レイアウトを利用するために役立ちます。ダイアログ ボックスは、3 行 5 列に分割されています。どの行と列にも、固定サイズが定義されていません。このため、各セルに配置された UI 要素は、ローカライズ時のサイズの増加や減少に対応できます。

<Grid.ColumnDefinitions>
  <ColumnDefinition x:Uid="ColumnDefinition_1" />
  <ColumnDefinition x:Uid="ColumnDefinition_2" />

[Open:] ラベルと ComboBox が配置されている最初の 2 列は、UI 全体の幅の 10%を使用します。

  <ColumnDefinition x:Uid="ColumnDefinition_3" SharedSizeGroup="Buttons" />
  <ColumnDefinition x:Uid="ColumnDefinition_4" SharedSizeGroup="Buttons" />
  <ColumnDefinition x:Uid="ColumnDefinition_5" SharedSizeGroup="Buttons" />
</Grid.ColumnDefinitions>

この例では、Grid のサイズ設定共有機能を使用しています。最後の 3 列は同じ SharedSizeGroup に配置され、この機能を利用しています。名前から推測できるとおり、このプロパティを使用すると、複数の列で同じサイズを共有できます。このため、"Browse…" がこれより長い文字列 "Durchsuchen…" にローカライズされた場合、小さい [OK] ボタンと極端に大きい [Durchsuchen…] ボタンが作成される代わりに、すべてのボタンの幅が広くなります。

Xml:lang

Xml:lang="en-US"

UI のルート要素に配置された XAML における xml:lang の処理に注目してください。このプロパティは、指定した要素のカルチャと、その子について記述します。この値は、WPF のいくつかの機能で使用され、ローカライズ時に適切に変更される必要があります。この値は、単語のハイフネーションとスペル チェックに使用する言語辞書を変更します。また、桁の表示と、フォントの代替システムが使用フォントを選択する方法にも影響します。最後に、このプロパティは、数字の表示方法と、複雑な文字を使用したテキストの整形方法にも影響します。既定値は "en-US" です。

サテライト リソース アセンブリのビルド

次の .csproj の行を見てください**。

<UICulture>en-US</UICulture>

UICulture プロパティが追加されています。これが en-US などの有効な CultureInfo 値に設定されている場合、プロジェクトのビルドによって、すべてのローカライズ可能リソースが含まれたサテライト アセンブリが生成されます。

<Resource Include="RunIcon.JPG">

<Localizable>False</Localizable>

</Resource>

RunIcon.JPG は、すべてのカルチャで同様に表示するため、ローカライズする必要がありません。サテライト アセンブリに含めるのではなく、言語に依存しないメイン アセンブリ内にこれを残すよう、LocalizableFalse を設定します。すべてのコンパイル不可能なリソースの Localizable は、既定で True に設定されます。

[Run] ダイアログのローカライズ

Parse

アプリケーションのビルド後、これをローカライズする最初の手順は、ローカライズ可能リソースをサテライト アセンブリから解析することです。ここでは、「LocBaml ツールのサンプル」に記載されているサンプルの LocBaml ツールを使用します。ただし、LocBaml はサンプル ツールに過ぎず、独自のローカリゼーション プロセスに合ったローカリゼーション ツールの構築を始める支援するためのものです。LocBaml で LocBaml /parse RunDialog.resources.dll /out: を実行して解析を行い、RunDialog.resources.dll.CSV ファイルを生成します。

ローカライズ

Unicode をサポートする任意の CSV エディタを使用して、このファイルを編集します。ローカライズのカテゴリが "None" であるすべてのエントリを、フィルタで除外します。次のエントリが表示されます。

リソース キー

ローカライズのカテゴリ

Button_1:System.Windows.Controls.Button.$Content

Button

OK

Button_2:System.Windows.Controls.Button.$Content

Button

Cancel

Button_3:System.Windows.Controls.Button.$Content

Button

Browse...

ComboBox_1:System.Windows.Controls.ComboBox.$Content

ComboBox

TextBlock_1:System.Windows.Controls.TextBlock.$Content

Text

Type the name of a program, folder, document, or Internet resource, and Windows will open it for you.

TextBlock_2:System.Windows.Controls.TextBlock.$Content

Text

Open:

Window_1:System.Windows.Window.Title

Title

Run

アプリケーションをドイツ語にローカライズするには、次の変換が必要です。

リソース キー

ローカライズのカテゴリ

Button_1:System.Windows.Controls.Button.$Content

Button

OK

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

Öffnen:

Window_1:System.Windows.Window.Title

Title

Run

生成

ローカリゼーションの最後の手順では、新しくローカライズされたサテライト アセンブリを作成します。これを行うには、次の LocBaml コマンドを使用します。

LocBaml.exe /generate RunDialog.resources.dll /trans:RunDialog.resources.dll.CSV /out: . /cul:de-DE

ドイツ語版 Windows では、メイン アセンブリの隣の de-DE フォルダにこの resources.dll が配置されている場合、en-US フォルダ内のリソースの代わりに、このリソースが自動的に読み込まれます。これをテストするためのドイツ語版の Windows を所有していない場合は、カルチャに、現在使用している Windows のカルチャ (en-US) を設定し、元の resources.dll を置き換えます。

サテライト リソースの読み込み

MyDialog.exe en-US\MyDialog.resources.dll de-DE\MyDialog.resources.dll

コード

元の英語の BAML

ローカライズされた BAML

カルチャに依存しないリソース

英語のその他のリソース

ドイツ語にローカライズされたその他のリソース

.NET Framework は、読み込むサテライト リソース アセンブリを、アプリケーションの Thread.CurrentThread.CurrentUICulture に基づいて自動的に選択します。既定では、使用している Windows OS のカルチャです。つまり、ドイツ語版 Windows を使用している場合は de-DE\MyDialog.resources.dll が読み込まれ、英語版 Windows を使用している場合は en-US\MyDialog.resources.dll が読み込まれます。プロジェクトの AssemblyInfo.* で NeutralResourcesLanguage を指定すると、アプリケーションの最終フォールバック リソースを設定できます。たとえば、次のように指定するとします。

[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]

こうすると、ドイツ語版 Windows で de-DE\MyDialog.resources.dll と de\MyDialog.resources.dll のどちらも使用できない場合に、en-US\MyDialog.resources.dll が使用されます。

Microsoft サウジアラビアのホームページ

次の図は、英語とアラビア語のホームページを示します。これらを作成するサンプル全体については、「グローバリゼーション ホームページのサンプル」を参照してください。

英語 :

English page

アラビア語 :

Arabic page

Microsoft のグローバルなホームページの設計

この Microsoft サウジアラビアの Web サイトのサンプルは、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 です。

ルート Page の FlowDirection を変更した場合、背景のグラデーション ブラシまでが正しく反転します。

FlowDirection="LeftToRight"

FlowDirection="RightToLeft"

固定サイズのパネルとコントロールの使用を回避する

Homepage.xaml を調べると、上部の DockPanel の UI 全体に対して固定の幅と高さが指定されていることを除けば、他に固定サイズがないことがわかります。ローカライズ後にソース テキストより長くなったテキストがクリップされるのを回避するため、固定サイズは使用しないようにします。WPF のパネルとコントロールは、含まれているコンテンツに基づいて自動的にサイズ変更されます。多くのコントロールは、最小サイズと最大サイズを設定して制御することもできます (MinWidth= "20" など)。Grid では、「*」を使用して相対的な幅と高さを設定したり (Width= "0.25*" など)、RunDialog の例に示されているセル サイズの共有機能を使用したりすることもできます。「グローバリゼーション実行ダイアログ ボックスのサンプル」を参照してください。

ローカリゼーション コメント

コンテンツが不明確で変換が困難な場合も少なくありません。開発者またはデザイナは、ローカリゼーション コメントを通じて、追加のコンテキストやコメントをローカライザに提供できます。たとえば、次の 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

This character is used as a decorative rule.

|

任意の要素のコンテンツやプロパティにコメントを配置するには、次の構文を使用します。

<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 には、要素のコンテンツやプロパティの readability、modifiability、および category を設定するための属性が用意されています。これらの属性を独自のローカリゼーション ツールで使用して、要素をロックしたり、非表示にしたり、並べ替えたりできます。詳細については、AttributesProperty を参照してください。このサンプルでは、LocBaml ツールがこれらの属性の値だけを出力します。WPF のすべてのコントロールには、これらの属性の既定値がありますが、オーバーライドすることもできます。たとえば、次の例では TextBlock_1 の既定のローカリゼーション属性をオーバーライドして、ローカライザがコンテンツを読み取ることはできても変更できないように設定します。

<TextBlock
x:Uid="TextBlock_1"
Localization.Attributes=
"$Content(Readable Unmodifiable)">
  Microsoft Corporation
</TextBlock>

WPF には、readability および modifiability の属性に加えて、UI の一般的なカテゴリの列挙体が用意されており、より多くのコンテキストをローカライザに提供するために使用できます。これらは、Text、Title、LabelButtonCheckBoxComboBoxListBoxMenuRadioButtonToolTipHyperlink、Document、XmlData、および Font です。プラットフォーム コントロールに対する WPF の既定のカテゴリも、次のように XAML 内でオーバーライドできます。

<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 ディレクトリの GlobalUserInterface.CompositeFont が使用され、そのコード ポイント範囲をサポートするフォントに自動的に置き換えられます。複合フォントは、その他のフォントと同様に機能し、要素の FontFamily (FontFamily= "Global User Interface") を設定することにより明示的に使用できます。独自の複合フォントを作成し、特定のコード ポイント範囲や言語で使用するフォントを指定することにより、フォントの代替設定を独自に指定することもできます。

複合フォントの詳細については、FontFamily を参照してください。

Microsoft ホームページのローカライズ

[Run] ダイアログの例と同じ手順に従って、このアプリケーションをローカライズできます。アラビア語にローカライズされた .csv ファイルについては、グローバリゼーション ホームページのサンプル を参照してください。