2013年8月29日木曜日

マルチリンガルで行こう(WPF編)

えー、前回いつ更新したか覚えてないくらいにはご無沙汰してます、はざまです。
今回は、趣味グラミングアプリを作っていてちょっとはまった部分を自分用メモも兼ねてエントリーにしておこうと思います。題材にするのはその名も、WPFLocalizationExtensionです。このライブラリ、名前の通りWPFで作成するアプリのローカライゼーションを容易にしてくれます。具体的にどんなことができるのかは公式サイトのイントロダクション動画を参照していただくとして、残念ながらこのライブラリーはドキュメンテーションの質がイマイチなので、ここでは準備方法と使用方法の解説をしたいと思います。

まず、インストール方法ですが、nuGetが使えるならそこから入手するのが一番楽です。というか、その方法しか試したことはありません。一からビルドする場合には、ご自身でその方法を調査してみてください。
インストールが終わったら、まずサンプルとして以下のような.xamlファイルを作成します。

<Window
    x:Class="WPFLocalizationExtensionExample.ExampleView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:lex="http://wpflocalizeextension.codeplex.com"
    lex:LocalizeDictionary.DesignCulture="en"
    lex:ResxLocalizationProvider.DefaultAssembly="WPFLocalizationExtension"
    lex:ResxLocalizationProvider.DefaultDictionary="StringResources">
    <Grid>
        <TextBlock Text="{lex:Loc ExampleTexts_HelloWorld}" />
    </Grid>
</Window>

上記のコードに関していくつか補足しておきます。まず5行目の式は見た目通り、WPFLocalizationExtensionの名前空間をlexという名前でXAMLに取り込むことを指定しています。なぜlexなのかは、公式サイトなどでそう推奨されているからとしか答えようがありません。
次の6~8行の式はこのXAMLファイル全体に影響するWPFLocalizationExtensionの設定です。具体的に上から"VSなどのデザイナーで表示する言語設定","WPFLocalizationExtensionがリソースを検索する際に使用するアセンブリー名","WPFLocalizationExtensionがリソースを検索する際に使用する.resxファイルの名前"となっています。これらの式はXAMLファイル中のいずれの場所にも記述できて逐次、設定を変更できるようです。
なお、ここに記すメモはRESXファイルをリソースとして使用することを前提としています。WPFLocalizationExtensionの機能として適切なILocalizationProviderを用意すれば、.csvや.xml、はたまた.txt,.jsonファイルなどもリソースファイルとして使用できるようですが、話が煩雑になるためここでは一切触れません。
さて、XAMLファイルを用意したら次は、リソースを作成します。公式サイトの説明によると、RESXファイルはVSで新規プロジェクトを作成した際にプロジェクト直下に作られるPropertiesという名前のフォルダーになければならないらしいので、その場所に今回はStringResources.resxという名前でRESXファイルを作成します。そして、このファイルに次のエントリーを追加します。
名前(key):ExampleTexts_HelloWorld
値(value):Hello world!
さらにそのリソースファイルを開いたままVS2012の場合は、ファイルタブの直下を見てください。
上の画像で示されたアクセス修飾子というプルダウンリストから"Public"を指定してください。これがないとライブラリーがリソースにアクセスできなくなってしまうようです。
ここまで作業が終わったら先ほどのXAMLファイルのデザイナータブを開いてみてください。全て正常に動作していれば、Hello world!という文字列を表示するウインドウがデザイナー画面に表示されるはずです。これでひとまず、WPFLocalizationExtensionから文字列リソースを扱う準備は整いました。ここからがいよいよ本領発揮となる多言語への対応です。ここでは日本語リソースを追加してみましょう。
まず、Propertiesフォルダー内にStringResources.ja.resxというファイルを作成します。そして、次のエントリーを追加してください。
名前(key):ExampleTexts_HelloWorld
値(value):こんにちは、世界!
エントリーを追加したら一旦IDEを終了し、適当なテキストエディターでIDEで開いていたプロジェクトファイルを開いてください。すると、そこに以下のような要素があるはずです。

<EmbeddedResource Include="Properties\StringResources.ja.resx">

この要素の中身を次のように書き換えてください。
<SubType>Designer</SubType>
<DependentUpon>StringResources.resx</DependentUpon>

書き換えが終わったらしっかり保存してIDEに戻りましょう。この状態でデザイナー画面を開き、XAMLファイル内のlex:LocalizeDictionary.DesignCultureの値をjaにすれば、晴れてウインドウ内に表示されるテキストが日本語化されるはずです。
これでWPFアプリケーションのグローバリゼーションは完了です。あとは、他の言語のRESXファイルを追加するなり、文字列以外のリソースを追加するなり色々試してみてください。WPFLocalizationExtensionは汎用性が高い分、使用方法が幾分煩雑になっていますが、適切な前準備さえ終えてしまえばコードに"WPFLocalizeExtension.Engine.LocalizeDictionary.Instance.Culture = 使用したい言語を表すSystem.Globalization.CultureInfoオブジェクト"の一文を追加するだけで表示する言語が変わるなど非常に使い勝手のいいライブラリーだと思います。



最後に、タイトルの(WPF編)という一言について補足します。WPF編と銘打っているからには今後、シリーズ化して他のプラットフォームでのグローバリゼーションの話題も出すんだろうなと突っ込まれても困ります。シリーズ化するかは未定です。