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 とそのサイズ共有機能を使用します。
ローカライズされたテキストはより多くのスペースを必要とすることが多いため、余白にスペースを確保しておきます。 余分なスペースがあれば、文字の張り出しに対応できます。
TextBlock で TextWrapping を有効にして、クリッピングを回避します。
xml:lang 属性を設定します。 この属性は、特定の要素のカルチャと、その子要素について記述します。 このプロパティの値は、WPF のいくつかの機能の動作を変更します。たとえば、ハイフネーション、スペル チェック、数字の置換、複雑な文字の整形、フォントの代替などの動作を変更します。 XAML における xml:lang の処理 の設定の詳細については、「WPF のグローバリゼーション」を参照してください。
さまざまな言語で使用されるフォントをより良く制御するには、カスタマイズした複合フォントを作成します。 既定では、WPF によって Windows\Fonts ディレクトリの GlobalUserInterface.CompositeFont が使用されます。
作成するナビゲーション アプリケーションが、右から左の方向にテキストを表示するカルチャにローカライズされる可能性がある場合は、各ページの FlowDirection を明示的に設定して、ページが NavigationWindow の FlowDirection を継承しないようにします。
ブラウザーの外でホストされるスタンドアロンのナビゲーション アプリケーションを作成する場合、初期アプリケーションの StartupUri に、ページ (<Application StartupUri="NavigationWindow.xaml"> など) ではなく NavigationWindow を設定します。 この設計を使用すると、ウィンドウとナビゲーション バーの FlowDirection を変更できます。 詳細および例については、グローバリゼーション ホームページのサンプルを参照してください。
WPF のローカリゼーションのベスト プラクティス
WPF ベースのアプリケーションをローカライズする場合、次のベスト プラクティスの実装を考慮してください。
ローカリゼーション コメントを使用して、ローカライザーに追加のコンテキストを提供します。
ローカリゼーションを制御するには、要素の Uid プロパティを選択的に省略するのではなく、ローカリゼーション属性を使用します。 詳細については、「ローカリゼーション属性とコメント」を参照してください。
XAML で Uid プロパティを追加して確認するには、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 形式を使用したローカリゼーション ワークフローについて説明します。これによって次のような利点が提供されます。
ビルド後にローカライズできます。
古いバージョンの XAML の BAML 形式を使用したローカリゼーションで、新しいバージョンの XAML の BAML 形式に更新できるので、開発と同時にローカライズできます。
XAML の BAML 形式は XAML をコンパイルした形式であるので、元のソース要素とセマンティクスをコンパイル時に検証できます。
ローカリゼーションのビルド プロセス
WPF アプリケーションを開発する場合の、ローカリゼーションのビルド プロセスは次のとおりです。
開発者が WPF アプリケーションを作成し、グローバル化します。 アプリケーションのコンパイル時に、言語に依存しないメイン アセンブリが生成されるように、プロジェクト ファイルで開発者が <UICulture>en-US</UICulture> を設定します。このアセンブリには、すべてのローカライズ可能リソースが含まれた、サテライトの .resources.dll ファイルがあります。ローカリゼーション APIs ではメイン アセンブリからの抽出がサポートされるので、必要に応じてソース言語をメイン アセンブリ内に残すこともできます。
ファイルをビルドにコンパイルすると、XAML が XAML の BAML 形式に変換されます。 カルチャに依存しない MyDialog.exe ファイルと、カルチャに依存する (英語の) MyDialog.resources.dll ファイルを、英語圏の顧客にリリースします。
ローカリゼーション ワークフロー
ローカライズされていない MyDialog.resources.dll ファイルがビルドされた後、ローカリゼーション プロセスが始まります。 System.Windows.Markup.Localizer の下の APIs が使用され、元の XAML 内の UI 要素とプロパティが、XAML の BAML 形式からキーと値のペアとして抽出されます。 ローカライザーは、キーと値のペアを使用して、アプリケーションをローカライズします。 ローカリゼーションの完了後、新しい値から新しい .resource.dll を生成できます。
キーと値のペアにおけるキーは、開発者が元の XAML に配置した x:Uid 値です。 これらの x:Uid 値を使用すると、ローカリゼーション時に開発者とローカライザーの間で発生する変更を、API で追跡およびマージすることができます。 たとえば、ローカライザーがローカライズを開始した後に開発者が UI を変更した場合、完了したローカリゼーション作業に開発の変更をマージして、失われる変換作業を最小限に抑えることができます。
次の図に、XAML の BAML 形式に基づく一般的なローカリゼーション ワークフローを示します。 この図では、開発者が英語のアプリケーションを作成しているものとします。 開発者が WPF アプリケーションを作成し、グローバル化します。 開発者は、ビルド時に言語に依存しないメイン アセンブリが生成されるように、プロジェクト ファイルに <UICulture>en-US</UICulture> を設定します。このアセンブリには、すべてのローカライズ可能リソースが含まれた、サテライトの .resources.dll があります。 WPF のローカリゼーション API ではメイン アセンブリからの抽出がサポートされるため、必要に応じてソース言語をメイン アセンブリ内に残すこともできます。 ビルド処理が完了すると、XAML は BAML にコンパイルされます。 カルチャに依存しない MyDialog.exe.resources.dll を、英語圏の顧客に出荷します。
WPF のローカリゼーションの例
ここでは、WPF アプリケーションをビルドおよびローカライズする方法の理解に役立つ、ローカライズされたアプリケーションの例を示します。
[Run] ダイアログ ボックスの例
次の図は、[Run] ダイアログ ボックスのサンプルの出力を示します。
次に示します。
ドイツ語 :
グローバルな [Run] ダイアログ ボックスの設計
この例では、WPF および XAML を使用して、[Run] ダイアログ ボックスを作成します。 このダイアログ ボックスは、Microsoft Windows の [スタート] メニューから使用可能な [ファイル名を指定して実行] ダイアログ ボックスと同じものです。
グローバルなダイアログ ボックスを作成するためのいくつかの要点を次に示します。
Automatic Layout
次の Window1.xaml の行を見てください。
<Window SizeToContent="WidthAndHeight">
上記のウィンドウのプロパティでは、ウィンドウのサイズがコンテンツのサイズに合わせて自動的に変更されます。 このプロパティは、ローカリゼーション後にサイズが大きくなるコンテンツが切り捨てられないようにします。また、ローカリゼーション後にコンテンツのサイズが小さくなる場合は、不要なスペースを削除します。
<Grid x:Uid="Grid_1">
WPF ローカリゼーションの APIs が正しく機能するためには、Uid プロパティが必要です。
これは、WPF ローカリゼーションの APIs によって、user interface (UI) の開発とローカリゼーション間の変更を追跡するために使用されます。 Uid プロパティを使用すると、UI の新しいバージョンを UI の古いローカリゼーションにマージできます。 Uid プロパティを追加するには、コマンド シェルで 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" です。
Building a Satellite Resource Assembly
次の .csproj の行を見てください。
<UICulture>en-US</UICulture>
UICulture 値が追加されています。 これが en-US などの有効な CultureInfo 値に設定されている場合、プロジェクトのビルドによって、すべてのローカライズ可能リソースが含まれたサテライト アセンブリが生成されます。
<Resource Include="RunIcon.JPG">
<Localizable>False</Localizable>
</Resource>
RunIcon.JPG は、すべてのカルチャで同様に表示するため、ローカライズする必要がありません。 サテライト アセンブリに含めるのではなく、言語に依存しないメイン アセンブリ内にこれを残すよう、Localizable を false に設定します。 すべてのコンパイル不可能なリソースの Localizable は、既定で true に設定されます。
[Run] ダイアログのローカライズ
Parse
アプリケーションのビルド後、これをローカライズする最初の手順は、ローカライズ可能リソースをサテライト アセンブリから解析することです。 ここでは、LocBaml ツールのサンプルにある、サンプルの LocBaml ツールを使用します。 ただし、LocBaml はサンプル ツールに過ぎず、独自のローカリゼーション プロセスに合ったローカリゼーション ツールの構築を始める支援するためのものです。 LocBaml で LocBaml /parse RunDialog.resources.dll /out: を実行して解析を行い、RunDialog.resources.dll.CSV ファイルを生成します。
Localize
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 |
Generate
ローカリゼーションの最後の手順では、新しくローカライズされたサテライト アセンブリを作成します。 これを行うには、次の 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 を置き換えます。
Satellite Resource Loading
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 サウジアラビアのホームページ
次の図は、英語とアラビア語のホームページを示します。 これらのグラフィックスを生成するサンプル全体については、グローバリゼーション ホームページのサンプルを参照してください。
次に示します。
アラビア語 :
Microsoft のグローバルなホームページの設計
この Microsoft サウジアラビアの Web サイトのサンプルは、RightToLeft 言語に提供されるグローバリゼーション機能を表しています。 ヘブライ語やアラビア語などの言語は右から左に読むため、多くの UI のレイアウトを、英語などの左から右に読む言語の場合とは大幅に変える必要があります。 左から右に読む言語と右から左に読む言語の間では、ローカリゼーションが困難な場合があります。 WPF は、そのようなローカリゼーションをはるかに簡単に行うことができるよう設計されています。
FlowDirection
Homepage.xaml を次に示します。
<Page x:Uid="Page_1" x:Class="MicrosoftSaudiArabiaHomepage.Homepage"
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://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 |
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 を設定するための属性が用意されています。これらの属性を独自のローカリゼーション ツールで使用して、要素をロックしたり、非表示にしたり、並べ替えたりできます。 詳細については、「Attributes」を参照してください。 このサンプルでは、LocBaml ツールがこれらの属性の値だけを出力します。 WPF のすべてのコントロールには、これらの属性の既定値がありますが、オーバーライドすることもできます。 たとえば、次の例では TextBlock_1 の既定のローカリゼーション属性をオーバーライドして、ローカライザーがコンテンツを読み取ることはできても変更できないように設定します。
<TextBlock
x:Uid="TextBlock_1"
Localization.Attributes=
"$Content(Readable Unmodifiable)">
Microsoft Corporation
</TextBlock>
WPF には、readability および modifiability の属性に加えて、UI の一般的なカテゴリの列挙体 (LocalizationCategory) が用意されており、より多くのコンテキストをローカライザーに提供するために使用できます。 プラットフォーム コントロールに対する 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 ファイルについては、グローバリゼーション ホームページのサンプルを参照してください。