はじめに
ここで行うのはResource Fileに全て書いておき、Form間で共有する方法。
なお、言語切り替えが行われるのはアプリを再起動した時としている。
サンプル
日本語と英語に対応している。
ラベルに書かれていることに意味はない。(別の方法でやっていた時の名残)
既定言語(英語)のテキストを入力するまで
- プロジェクト上に「Resources」みたいなフォルダを作る。
- 作ったフォルダ上で右クリック → 追加 → 新しい項目 → リソースファイルを選択 → Stringsみたいな名前を付ける。Strings.resxというファイルができます。
このファイルが既定言語(英語)のテキストを保存していくファイルになります。 - Strings.resxをダブルクリックする → 下の画像のような画面になるので、左上の「+」をクリックする
- 下のようなダイアログが出る。「名前」に分かりやすい名前(どこのテキストにするか分かると良いかも)を設定 → 文字ならタイプはStringのまま → 「値」に表示したいテキストを入力する。
- ダイアログを閉じる。ここまでで既定言語のテキスト入力が完了します。
2つ目以降の言語を入力するまで
- ソリューションエクスプローラでStrings.resxをコピー&貼り付け。名前をStrings.ja.resxなどに変える。Stringsの後にくる「.ja」はカルチャコードというもので、対応する言語に沿ったものにする。
- 先ほどの手順4を行う。ただし「名前」の欄に入力するものはString.resxと同じものにする。同じ「名前」で紐づけることで、「値」に入力する2つ目以降の言語のテキストが既定言語のテキストと対応付けられる。例えばこの画像では、BtnChineseという名前に、1行目に入力されているテキストが紐づいている。
コード側で参照するまで
フォームをロードする部分に以下のように書くことで、コントロールのテキストをリソースファイルと紐づけることができる。
private void Form1_Load(object sender, EventArgs e)
{
// CurrentUICultureに応じて自動的にen/jaが切り替わる
BtnJapanese.Text = Strings.BtnJapanese;
BtnEnglish.Text = Strings.BtnEnglish;
BtnChinese.Text = Strings.BtnChinese;
label1.Text = Strings.label1_text;
label2.Text = Strings.label2_text;
}
言語切り替えボタンには以下のように書くことで、
切り替えた言語を保存して、次に立ち上げた際に反映させることが可能になる。
private void BtnEnglish_Click(object sender, EventArgs e)
{
Properties.Settings.Default.Language = "en";
Properties.Settings.Default.Save();
MessageBox.Show(Strings.MsgRestartRequired);
}
最後に、Main()を以下のように書けば完成。
[STAThread]
static void Main()
{
// 保存済みの言語設定を読み込む
string lang = Properties.Settings.Default.Language;
if (string.IsNullOrEmpty(lang))
{
lang = "ja"; // 初回起動時の既定値
}
var culture = new CultureInfo(lang);
Thread.CurrentThread.CurrentUICulture = culture;
Thread.CurrentThread.CurrentCulture = culture;
Application.Run(new Form1());
}
補足
Strings.BtnJapaneseのようにアクセスできる理由
Strings.resxを生成する際、Strings.Designer.csが自動生成される。
この中にコードも自動再生されているが、それがあると静的アクセスができる。
クリックイベントの中身について
Properties.Settings.Default.Language = "en";
Properties.Settings.Default.Save();
1行目では、Properties.Settings.Defaultで設定オブジェクトのインスタンスを取得し、そのLanguageプロパティに文字列として"en"を代入している。
この時点ではアプリ設定ファイルに書き込まれたわけではない。
2行目では、Save()メソッドを呼び出している。
これを行うことで実際に書き込むことができる。
Main()の中身について
1行ずつコメントを残しておく。
-
[STAThread]はメソッドに付与される属性らしい。私には詳細がよくわかっていない。 -
string lang = Properties.Settings.Default.Language;は以前設定した言語設定を読み込むもの。初回起動時はここは空文字になる。 -
if (string.IsNullOrEmpty(lang))空文字であればこの中に分岐する。lang = "ja"とすれば初回起動時には日本語が選択される。言語切り替えを行わずにアプリを終了した場合も同様。 -
var culture = new CultureInfo(lang);の右辺は.NETに標準で用意されているもの。「どの言語・どの地域」という情報を表すオブジェクト。 -
Thread.CurrentThreadは今実行されているスレッドを表すオブジェクト。 -
CurrentUICultureプロパティにCultureInfoを参照させることで、.resxファイルから文字列を取得する際、指定したカルチャを基準に選ばせることができる。 -
CurrentCultureの方はこのアプリでは使っていないが、日次や通貨についても同様に地域に合わせた表示に変えてくれるというもの。