スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
Prev.    Category    Next 

WPF での文字列リソースの利用と国際化

今回は WPF で文字列リソースを使う方法と国際化に関する記事です。

WPF では、文字列リソースを使ってアプリケーションを作っておけば、簡単に国際化することができます。
ここで "文字列リソースを使う"といっているのは、文字列をリソースファイルにまとめて定義し、 それを WPF のラベルやコード内のメッセージに使うことを意味しています。
"国際化する予定はない"という場合も多いとは思います。 その場合でも、コード内に文字列を直接書くのはあまり良くないので、 リソースを使ったコードと文字列の分離だけはやっておいた方がいいでしょう。


これから、サンプルアプリの作成手順にあわせて、リソースの利用法と国際化について説明していきたいと思います。

国際化の方法については以下のサイトを参考にさせて頂きました。参考というよりほぼ一緒ですが、ちょっと視点を変えて解説したつもりです。

文字列リソースの使用

最初はまだ国際化せずに、文字列リソースを利用しただけのアプリケーションを作成することにします。

まず "WpfI18n" という名前で [WPF アプリケーション] を新規作成します。
初期の構成は次のようになっています。
cs_i18n_startproj.png

リリースファイルの登録と作成

リソースファイルを使えるようにするためには、 App.xaml にリソースを登録する記述を追加します。

App.xaml :
 <Application x:Class="WpfI18n.App"
              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
              xmlns:properties="clr-namespace:WpfI18n.Properties"
              StartupUri="MainWindow.xaml">
     <Application.Resources>
         <properties:Resources x:Key="resources" />
     </Application.Resources>
 </Application>
Resources.resx がリソースファイルです。これを編集して文字列リソースを定義していきます。
国際化時のデフォルトの文字列とするので、英語版で作成します。
English resource

アクセス修飾子は Public を指定します。
ここでいったんビルドを行なって下さい。リソースを編集した場合、ビルドしていないと選択時の候補などが更新されないことがあります。

レイアウト

MainWindow のサイズを適当に変更し、ボタンを一つ配置します。 名前は buttonGreet としておきます。
cs_i18n_layout.png

サンプルなのでてきとうですが、実際に国際化するには Panel などのコントロールを利用して、 サイズや位置を直接指定しないようにする必要があります。 Qt, Gtk+ といった Unix 系のツールキットでは、伸縮を考慮したレイアウトの方が普通です。
Windows ではようやく WPF からちゃんと対応しました。 しかし、 VS の GUI ビルダーでは勝手にサイズなどをいれてしまうため、 いちいち [リセット] していく必要があります。 この辺はもう一息といったところです。

UI からのリソース利用

[Content](表示内容)を文字列で直接入力するのではなく、 データバインドを利用する ところがポイントです。
サンプルでは、ボタン(buttonGreet)とウィンドウのタイトルを文字列リソースで指定しています。

Content のところでデータバインドを設定するダイアログを開きます。
ここで [StaticResource] を選び、各リソース名を選択します。

cs_i18n_databind_menu.png cs_i18n_databind_dialog.png

VS2010 の場合はちょっとわかりづらいですが、 [ソース] で [StaticResource]、 [Application.Resources]と順に選択してから、[パス]で各リソース名を選択します。
データバインドダイアログ(VS2010)

コードからのリソース利用

コードから文字リソースを利用する例も挙げておきます。
ボタン(buttonGreet) をダブルクリックして、コールバック用のメソッドのひな形を追加します。 そこに以下の記述を追加すれば、 buttonGreet を押すと文字列リソースで定義されたメッセージを表示するようになります。

MainWindow.xaml.cs :
        private void buttonGreet_Click(object sender, RoutedEventArgs e)
        {
            MessageBox.Show(Properties.Resources.MessageHello);
        }
ここでビルドして、実行してみてください。 文字列リソースで定義した文字がアプリケーションで使用されていることが確認できると思います。
cs_i18n_exec.png

国際化

リリースファイルの作成

次の手順で、[ソリューション エクスプローラー] の操作を行い、日本語の文字列リソースファイルを作成します。
  1. Resources.resx をコピー
  2. プロジェクトに対して貼り付け
  3. Resources.ja-JP.resx と名前を変更
  4. [Properties] に移動
cs_i18n_proj_ja.png

作成したリソースファイルを開き、値を日本語に変更します。 このときアクセス修飾子は [コード生成なし] にします。
cs_i18n_res_ja.png

ビルドして、実行してみてください。これだけで日本語に変更されているはずです。
cs_i18n_exec_ja.png

リリースファイルの仕組み

英語で表示されていた場合の仕組みは次のようになっています。
  1. ユーザーの設定は 言語:日本語(ja)、地域:日本(JP)
  2. ja-JP のリソースを探す
       → みつからない
  3. デフォルト(Resources.resx)のリソースを使用
  4. 英語で表示
Resources.ja-JP.resx の作成後は、"ja-JP" のリソースが見つかり、日本語で表示されるようになります。


"ja-JP" というのは、 言語、地域を指定する Culture 名です。どのよう文字を指定するかは以下のサイトで確認できます。 通常の開発では文字列リソースは追加や削除などの編集を繰り返すことになると思います。

例えば、 日本語のリソース定義が足りていなかったとしたら、どうなるでしょうか?
この場合はその文字だけデフォルト(英語)のリソースが使用されます。

このように文字列リソースはファイル、項目などが見つからない場合にはデフォルトが使われます。 日本語をデフォルトにしていると英語環境では文字化けする危険があります。 デフォルトは英語 の方がいいでしょう。 (逆に英語が混じっていても、まずバグとは言われません)

なお、リソースファイル(.resx)の実態は XML フォーマットのテキストファイルです。
テキスト差分表示のツールなどで対応を確認することもできます。

生成ファイル

日本語用の文字列リソースファイルを作ってビルドすると、 exe のところに次のようなファイルも生成されます。
リリースする場合にはこの構成でリソース用の dll を付けてリリースしてください。
(Debug|Release)/
  ├ WpfI18n.exe
  └ ja-JP/
      └ WpfI18n.resources.dll

国際化のテスト

日本語のリソースを作成したら、日本語で表示されるのはいいのですが、 今度は英語が表示できません。表示言語を切り替えて、各言語での表示を確認する方法について説明します。


ちなみに、 英語と日本語だけでいいということであれば、"ja-JP" のフォルダーを削除すれば、 英語で表示することも可能です。

ユーザー環境の変更

言語、地域はユーザーごとに設定します。
これは [コントロールパネル] から変更することができます。

コントロールパネルの表示スタイルによっても変わりますが、 [表示言語の選択][地域と言語] の項目を選択すると、 ダイアログが表示されます。 ここで表示言語を変更します。
cs_i18n_setlang.png

ただし、他言語が一つもインストールされていないと選択項目は表示されません。 インストールできるかどうかは OS のタイプ(Ultimate など)によります。
cs_i18n_setlang.png

言語の設定を反映させるにはログオフをする必要があります。 ちゃんとテストする場合などはテスト用のユーザーを作り、 それを切り替えて確認することになるかと思います。

ただし、開発中の確認などではそれも面倒です。 次節で起動時にプログラムの表示言語を変える方法を説明します。
こちらは他言語がインストールされていなくても表示することができます。

起動時に表示言語を変えるコードを加える

次の方法でカルチャー名を指定して起動できるような修正を行います。
  • 環境変数
  • コマンド引数
サンプルでは両方できるようにしていますが、好きな方を使用してください。
さらに改造すれば、ファイルから読み取ったり、保存していた設定(次回の起動時から有効)で指定したり といったこともできるのではないかと思います。


起動時に実行するメソッドを追加
アプリケーションの XAML に Startup の要素で起動時に実行するメソッドを追加します。

App.xaml :
 <Application x:Class="WpfI18n.App"
              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
              xmlns:properties="clr-namespace:WpfI18n.Properties"
              StartupUri="MainWindow.xaml" Startup="Application_Startup">
     <Application.Resources>
:
VS 上で追加すれば、関数名やコードへのひな形も自動的に追加されます。


カルチャー情報の変更
追加した起動時のメソッドで現在のスレッドのカルチャー情報を変更します。
GUI の表示を変えるため、 CurrentCulture だけでなく CurrentUICulture も変更しているところに注意してください。

App.xaml.cs :
         private void SetCurrentCulture(string culname)
         {
             Thread.CurrentThread.CurrentCulture = new CultureInfo(culname);
             Thread.CurrentThread.CurrentUICulture = new CultureInfo(culname);
         }
 
         private void Application_Startup(object sender, StartupEventArgs e)
         {
             // 環境変数を使用
             string langstr = System.Environment.GetEnvironmentVariable("TEMP_LANG");
             if (langstr != null)
             {
                 SetCurrentCulture(langstr);
             }
 
             // 引数を使用
             if (0 < e.Args.Length)
             {
                 SetCurrentCulture(e.Args[0]);
             }
         }
スレッドやカルチャー情報を使うための名前空間も追加する必要があります。
 using System.Threading;     // 追加
 using System.Globalization; // 追加

実行
次のように引数を指定して実行すると、英語版画面が表示されます。
 ~/cs/i18n/WpfI18n $ ./bin/Debug/WpfI18n.exe en-US
ただし、サンプルでは en-US のリソースを表示しているわけではありません。 en-US のリソースがないため、デフォルトのリソースを使用した結果、英語版で表示されています。

サンプルコード

作成したサンプルアプリのコードもあげておきます。 なお、サンプルを順に作らずに、サンプルコードをそのままビルドして実行すると XAML の解析で実行時例外が発生する時があります。
この場合、 改行を足すなど、なんでもいいので、 MainWindow.xaml.cs ファイルをちょっと修正して、ビルドしなおすと解消することが多いです。 私も原因はよくわかってないのですが...

追記 2013-09-17
resx ファイルを StaticResource から利用するとどうしても出てしまうバグのようでした。
マークアップ拡張を使って resx ファイルを利用する方法の記事を追加しました。 また、国際化の切り替えのコードで Thread.CurrentThread.CurrentUICulture しか設定していなかったので、CurrentCulture の方も設定するように変更しました。

関連記事
スポンサーサイト
Prev.    Category    Next 

Facebook コメント


コメント

コメントの投稿

Font & Icon
非公開コメント

このページをシェア
アクセスカウンター
アクセスランキング
[ジャンルランキング]
コンピュータ
25位
アクセスランキングを見る>>

[サブジャンルランキング]
プログラミング
3位
アクセスランキングを見る>>
カレンダー(アーカイブ)
プルダウン 降順 昇順 年別

06月 | 2017年07月 | 08月
- - - - - - 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 - - - - -


はてな新着記事
はてな人気記事
ブロとも申請フォーム
プロフィール

yohshiy

Author:yohshiy
職業プログラマー。
仕事は主に C++ ですが、軽い言語マニアなので、色々使っています。

はてブ:yohshiy のブックマーク
Twitter:@yohshiy

サイト紹介
プログラミング好きのブログです。プログラミング関連の話題や公開ソフトの開発記などを雑多に書いてます。ただ、たまに英語やネット系の話になることも。
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。