チラホラ見かけた情報だけだと実務には足りない気がしたので、Windows Formsでの多言語対応について少々。まず前提として、デフォルトの言語を決めておき、それ以外の文言を必要に応じて追加するという方法を取ります。
デフォルトは日本語か英語でしょう、多国語対応がタイ語、スペイン語やポルトガル語などまで意識するようなものなら英語をデフォルトとしたほうがよさそうです。
1.Formのリソース
よくあるのがコチラ。Formを多言語対応する場合、
- FormのLanguageプロパティが(規定値)の状態で、Formを作成します。
- FormのLocalizableプロパティをTrueにし、Languageプロパティを多言語対応する言語に変更した上で、1で編集したFormを編集しなおします。
- 必要言語分、2を繰り返します。
ステップ2でLanguageを変更後、Formのコントロールを初めて変更するタイミングで新たなリソースファイルが作成されます。
この例では規定の言語用のTestForm.resxと、日本語用のTestForm.ja.resx、ドイツ語用のTestForm.de.resxができています。これをビルドすると実行ファイルに[ja]とか、[de]とかいうフォルダがあり、リソースだけを含んだDLL(サテライトアセンブリと呼びます)ができます。実行時にCurrentUICultureに基づいて自動的に読みだしてくれます。
2.その他のリソース
MessageBoxやファイル出力などForm以外でも文言が必要な場合はあります。そのような文言も多言語対応する場合はResources.resxファイルに格納します。これも初期状態では規定の言語用のファイルしかありませんので、多言語対応する言語ごとに作り直します。
多言語用のresxファイルは、規定の言語用のResources.resxファイルをコピーしてプロジェクトに張り付けした後、適切なカルチャコードを加えてPropertiesフォルダに格納します。カルチャーコードはネット上で調べてもわかるし、Formを多言語対応する時にはカルチャコードがわかるのでそれを真似て作ればOKです。
アクセスするときはこんな感じ。
Console.WriteLine(Properties.Resources.IDS_BUTTON);
これも同じくビルドすると先ほど同様サテライトアセンブリに組込まれるので、あとはCurrentCultureに基づいてロードされます。
3.文言翻訳運用
確かにメインは以上なんですが、『これでお終い』って言われると・・・?オレオレ翻訳ならOkだけど、普通は翻訳家・翻訳業者に頼んだり、プルーフするはずで実際の運用だとどう考えてもこの辺のリソースをまとめる作業が必要になる。
例えば文言リストを一覧形式で保持する必要があるならExcelで運用しといて、翻訳が完了したらresxファイルを作るって手がある。つまり、Excelにこんな感じで文字列一覧を作って、
このExcelファイルを読みこむを↓のような感じで作って、
ExcelToResx.cs
namespace MultiLanguageWindowsFormsApp.Tool { using System.Resources; using System.Linq; using LinqToExcel; class ExcelToResx { private string excelPath; public ExcelToResx(string excelPath) { this.excelPath = excelPath; } // language="日本語"とか。 public void Save(string filePath, string language) { var factory = new ExcelQueryFactory(excelPath); var query = factory.Worksheet("Sheet1"); using (var writer = new ResXResourceWriter(filePath)) { foreach (var item in query){ writer.AddResource(item["ID"], item[language]); } } } } }
Resources.rexもForm.resxも上のExcelにまとめて作ってやって、どのリソースファイルなのかを示す列を作っておけば簡単です。LinqToExcelなんだから、ファイルでLoop回しながらSelectするという手があります、あとは出力されるresxファイルをプロジェクトに登録しなおせばOK。
文字数制限チェックはExcelVBAなどでもチェックできます。また、ResXResourceWriterは書き込み専用で “追記” ができないので、リソースファイルの使い方によってはFormで参照する文字列も全てResource.resxに定義しておき、FormのコンストラクタでResourcesを参照する構成にすれば翻訳対象のresxファイルが一つになるので管理しやすいかもしれません。