酢ろぐ!

カレーが嫌いなスマートフォンアプリプログラマのブログ。

Windowsストアアプリでローカライズしてみる(プログラム編)

Windowsストアアプリで各言語の文字列リソースを用意して、多言語対応するにはどうすれば良いのかをご紹介します。今回は、プログラム上でのローカライズの方法についてご紹介します。

ソリューション エクスプローラー

アプリの構成は以下のように「en」「ja」のそれぞれのフォルダ配下に「リソースファイル(.resw)」を配置しています。名前は両方とも同じStringResources.reswと名前を付けています。


StringResources.reswの定義値

は以下の通りです。

en
名前
LabelSave Save
TextErrorOpenPicker Failed open a picker.
TitleError Error
ja
名前
LabelSave 保存
TextErrorOpenPicker ピッカーの起動に失敗しました
TitleError エラー

ソースコード

Windows.ApplicationModel.Resources.Core名前空間のResourceManagerクラスから現在実行中のアプリケーションのリソースマップを取得します。

    // リソースマップを作成
    var map = ResourceManager.Current.MainResourceMap;
    // StringResources.reswの中に含まれている「LabelSave」の値を取り出し
    var labelSave = map.GetValue("StringResources/LabelSave").ValueAsString;

使い方

MainPage.xaml.csのコンストラクタ内で、設定されている言語にマッチした値を取得します。例えば、ここではアプリバーのボタンのテキスト部分を言語設定によって変更させます。

/// <summary>
/// 多くのアプリケーションに共通の特性を指定する基本ページ。
/// </summary>
public sealed partial class MainPage : Mosaic.Common.LayoutAwarePage
{
    public MainPage()
    {
        this.InitializeComponent();
        
        // リソースマップを作成
        var map = ResourceManager.Current.MainResourceMap;

        // AppBar上のボタンをテキスト部分を変更
        AutomationProperties.SetName(btnSave, map.GetValue("StringResources/LabelSave").ValueAsString);
        AutomationProperties.SetName(btnPhoto, map.GetValue("StringResources/LabelPhoto").ValueAsString);
        AutomationProperties.SetName(btnFolder, map.GetValue("StringResources/LabelFolder").ValueAsString);
    }

UI要素であればXAMLから直接リソースを指定してしまった方がよいかもしれませんね。プログラム上で言語設定によって異なる文字列を使う例としては、メッセージダイアログでエラー文を表示させるときに使えるかもしれません。

以下のようなファイルピッカーの起動に失敗した場合には、リソースのTitleErrorとTextErrorOpenPickerの文字列を取得してきて、MessageDialogへ表示させています。

    try
    {
        file = await picker.PickSingleFileAsync();
        if (file == null)
        {
            // ユーザーのキャンセルによってピッカーが
            // 閉じられたのでメッセージを出さない
            return;
        }
    }
    catch
    {
        // スナップ状態でピッカーを開こうとしたり、
        // その他諸々の理由でピッカーで例外が発生した場合

        // リソースマップを作成
        var map = ResourceManager.Current.MainResourceMap;
        var message = map.GetValue("StringResources/TextErrorOpenPicker").ValueAsString;
        var title = map.GetValue("StringResources/TitleError").ValueAsString;

        var dlg = new MessageDialog(message, title);
        dlg.ShowAsync();
        return;
    }

追記

日本語表記の部分は、「ja」じゃなくて「ja-jp」の方が良いかも。好みに合わせてください。