ポンコツXAMLer奮闘記

C#(主にXAML)関連のメモ書きがメインです。

言語切替機能を実装する(任意のロケールIDを指定できる)

だいぶ時間が空いてしまいました。。。

前回はOSのデフォルトロケールIDに従って言語リソースを入れ替える方法を紹介しました。

nakasato-work.hatenablog.com

今回は、任意のロケールIDを指定することで、言語リソースを入れ替える方法を紹介します。

NuGetで、「Prism.Mvvm」をインストールしてください。(BindableBaseを使用する為)

次に、以下のクラスを定義します。

namespace TestApp
{
    public class CResourceService : BindableBase
    {

        #region singleton members

        private static readonly CResourceService _current = new CResourceService();
        public static CResourceService Current
        {
            get { return _current; }
        }

        #endregion

        private readonly TestApp.Properties.Resources _resources = new Resources();

        /// <summary>
        /// 多言語化されたリソースを取得します。
        /// </summary>
        public TestApp.Properties.Resources Resources
        {
            get { return this._resources; }
        }

        /// <summary>
        /// 指定されたカルチャ名を使用して、リソースのカルチャを変更します。
        /// </summary>
        /// <param name="name">カルチャの名前。</param>
        public void ChangeCulture(string name)
        {
            Resources.Culture = CultureInfo.GetCultureInfo(name);
            this.OnPropertyChanged("Resources");
        }
    }
}

まず、Resourcesプロパティがカレントの言語リソースです。

ChangeCultureでロケールID("ja"や"de"等)を渡すと、Resourcesの言語リソースが切り替わります。

ロケールIDの一覧はロケール ID (LCID) の一覧を参照してください。

使い方は以下です。

CResourceService.Current.ChangeCulture("ja");

コンボボックス等で言語リソースを切り替えたい場合、key=コンボボックス表示文字列、Value=ロケールIDの連想配列を作成しておくと、簡単に言語リソースを切り替えることができます。

Dictionary<string, string> dict = new Dictionary<string, string>();

dict["日本語"] = "ja";
dict["英語"] = "en";
dict["中国語(シンガポール)"] = "zh-sg";

こんな感じの連想配列ですね。

さぁ、ここまで来たら、後はGUIバインドするだけです!!(長かった。。。)

前回紹介したXAMLを元に修正すると、以下のようになります。

<Page
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:app="clr-namespace:TestApp"

    <-! 省略 -->

    <Button Content="{Binding Source={x:Static app:CResourceService.Current}, Path=Resources.[リソース名], Mode=OneWay}"/>

ちょっとContentのバインド指定が長くなってしまいます。。。(^^;)

これで任意のロケールIDを指定して言語リソースを切り替えることができるようになりました!

今回、序盤に登場したPrismについては全く触れませんでした。

しかし、このPrismはXAMLを征する上でかなり重要な役割を果たしてくれます。
数年前に比べてPrismに関するネット記事も増えているので、是非とも検索してみてください。