Skip to content

MS_WindowsFormsGlobalization

nishi_74322014 edited this page Aug 21, 2026 · 1 revision

Windows Formsの国際化対応

概要

Windows Forms の国際化対応方法について説明する。

国際化機能で

できること

  • Windows Form では、Form のデザインタイム・プロパティに存在する
    Language プロパティを変更することにより、
    各カルチャ用の画面をデザイナ上で作成できる。
  • 画面上のコントロールの配置・キャプションなどの各種プロパティ値を保存する
    リソース ファイルが選択した言語毎に生成・適用される

補足(仕組み): Windows Forms のローカライズは、
デザイナが .resx を自動生成するという点が特徴的である。

Form1.cs
Form1.Designer.cs
Form1.resx          ← Localizable = true にすると、既定カルチャの
                       プロパティ値がここに移動する
Form1.ja.resx       ← Language = 日本語 にして編集すると生成される
Form1.en.resx

手順:

① フォームの Localizable プロパティを true にする
     → すべてのプロパティ値が Form1.resx に移される
     → InitializeComponent が ComponentResourceManager 経由になる

② Language プロパティを「日本語」等に切り替える
     → その状態で編集すると Form1.ja.resx に差分が保存される

③ 実行時は CurrentUICulture に応じて自動的に適用される

文言だけでなく、位置・サイズ・フォントも言語ごとに変えられる
のが Windows Forms の強みである
(英語だとラベルが長くなる、といった問題に対処しやすい)。

できないこと

Windows Formsの機能で以下には対応していないことが判明しています。

  • コントロールの階層型プロパティ値をカルチャ毎に変える
  • DataGrid の列の順番をカルチャ毎に変える

できることを確認しながら実装する様にしてください。

補足(この制約の意味と回避策): 原文の指摘は
デザイナによる自動ローカライズの限界を突いたものである。

【階層型プロパティ】
   ListView.Columns[0].Text、TreeView.Nodes[...] など
     → デザイナは「コレクションの中身」を
       カルチャ別に差分保存できない

【DataGrid(View)の列順】
   列の並びは Index で管理されており、
   ローカライズの対象外

**回避策は「コードで明示的に適用する」**ことである。

// 起動時(または Load 時)にリソースから設定する
var rm = Strings.ResourceManager;   // 自前の .resx

listView1.Columns[0].Text = rm.GetString("Col_Name");
listView1.Columns[1].Text = rm.GetString("Col_Age");

// 列順もカルチャで切り替える
if (CultureInfo.CurrentUICulture.TwoLetterISOLanguageName == "en")
    dataGridView1.Columns["Name"].DisplayIndex = 0;

設計上の指針:

対象 手段
静的なラベル・ボタン デザイナ(Localizable
動的に生成する項目(列、ノード、メニュー) コードで ResourceManager から取得
メッセージ ボックス コードで取得
実行中の言語切り替え 画面を作り直す(後述)

Localizable = true にすると .resx が肥大する
(全プロパティが保存される)ため、
文言だけを切り替えたい場合は、
デザイナを使わずコードで設定する方が管理しやすい

という判断もあり得る。

補足(実行中の言語切り替え): Windows Forms のローカライズは
InitializeComponent の時点で適用されるため、
起動後に言語を変えても既存の画面には反映されない

// 切り替え後、フォームを作り直す必要がある
Thread.CurrentThread.CurrentUICulture = new CultureInfo("en");
var f = new MainForm();
f.Show();
this.Close();

あるいは、ComponentResourceManager
手動で再適用する方法もある。

var rm = new ComponentResourceManager(typeof(MainForm));
foreach (Control c in this.Controls) rm.ApplyResources(c, c.Name);
rm.ApplyResources(this, "$this");

「再起動を促す」のが最も確実で、実務でもよく採られる。

補足(.NET Core 以降の Windows Forms): Windows Forms は
.NET Core 3.0 以降でも利用可能であり、
ローカライズの仕組みも同じである
.NET Coreへの移行)。

ただし、次の点が変わっている。

.NET Framework .NET(Core 系)
.resx の扱い 同じ 同じ
サテライト アセンブリ 同じ 同じリソースファイル
既定のエンコーディング ANSI UTF-8文字コード
出力言語の絞り込み SatelliteResourceLanguages
BinaryFormatter 使える 削除.resx の一部の型に影響)

最後の点が移行時の落とし穴で、
.resx独自のシリアライズ可能な型を格納していると、
.NET の Serialize で述べた
BinaryFormatter の削除により読めなくなる場合がある。
文字列・画像・アイコンといった標準的な型なら問題ない

参考

プロジェクトをビルドすると、カルチャ毎にフォルダが分けられて DLL ファイルが生成される。
これらの DLL ファイルは、単一のカルチャのリソース(=文字列や画像などの情報)のみを
含むアセンブリとなるので、通常のメイン・アセンブリに対比して、
「サテライト・アセンブリ」と呼ばれる。

Microsoft Learn


Tags: 移行, .NET開発, UIサブシステム, Windows Forms, 国際化対応

NetDevInfraWiki

マイクロソフト系技術情報 Wiki
Open 棟梁 Wiki

(未着手)

開発基盤部会 Wiki

移行管理: DONETODO

Clone this wiki locally