-
Notifications
You must be signed in to change notification settings - Fork 0
MS_WindowsFormsGlobalization
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(文字コード) 出力言語の絞り込み - SatelliteResourceLanguagesBinaryFormatter 使える 削除( .resxの一部の型に影響)最後の点が移行時の落とし穴で、
.resxに独自のシリアライズ可能な型を格納していると、
.NET の Serialize で述べた
BinaryFormatterの削除により読めなくなる場合がある。
文字列・画像・アイコンといった標準的な型なら問題ない。
- @IT > Insider.NET > .NET TIPS > Windowsフォームを多言語対応にするには?
http://www.atmarkit.co.jp/fdotnet/dotnettips/314winmultilang/winmultilang.html
プロジェクトをビルドすると、カルチャ毎にフォルダが分けられて DLL ファイルが生成される。
これらの DLL ファイルは、単一のカルチャのリソース(=文字列や画像などの情報)のみを
含むアセンブリとなるので、通常のメイン・アセンブリに対比して、
「サテライト・アセンブリ」と呼ばれる。
- C#による多言語対応アプリケーション開発のコツ(1-3):CodeZine
http://codezine.jp/article/detail/3288 - 多言語対応 - C# フォーム しっかり入門
http://www.wgag.net/csforms/0087.html
- Windows フォームのグローバル化
https://learn.microsoft.com/ja-jp/dotnet/desktop/winforms/advanced/globalizing-windows-forms - Windows フォームのローカライズ
https://learn.microsoft.com/ja-jp/dotnet/desktop/winforms/advanced/localizing-windows-forms
Tags: 移行, .NET開発, UIサブシステム, Windows Forms, 国際化対応
このWikiは「Open棟梁Project」,「OSSコンソーシアム 開発基盤部会」によって運営されています。