ブログトップ 記事一覧 ログイン 無料ブログ開設

かずきのBlog@Hatena このページをアンテナに追加 RSSフィード Twitter

2011-03-09

WPFアプリケーションの国際化対応

リソースファイルを使う方法が簡単そうなので、試してみました。参考にしたのは以下のサイトというか、ほぼそのままですね。自分用メモという意味合いが強いです。

デフォルトで用意されてるResources.resxに加えてResources.ja-JP.resxを作成します。

f:id:okazuki:20110309234805j:image

中身はこんなかんじ。アクセス修飾子をPublicにしておくのがポイントです。

f:id:okazuki:20110309234806j:image

Resources.ja-JP.resxの中身はこんなかんじです。同じキーに対して違う文字列を割り当ててます。こちらはコード生成なしになってるのがポイントですね。(自動でなしになってるはず)

f:id:okazuki:20110309234807j:image

そして、このクラスをApp.xamlのResourcesとして登録します。

<Application x:Class="WpfResource.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:properties="clr-namespace:WpfResource.Properties"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
        <!-- Resourcesに登録しておく -->
        <properties:Resources x:Key="resources" />
    </Application.Resources>
</Application>

同じリソースという言葉が出てきますが、WPFのResourcesとResources.resxは別物です。

画面にボタンを置いたら、このresourcesのButtonTextをバインドしてみます。これはVisual Studioのデザイナからさくっとできます。

f:id:okazuki:20110309234808j:image

いい世の中ですね。XAML的には以下のようなものが作成されます。

<Button Content="{Binding Source={StaticResource resources}, Path=ButtonText}" Height="23" HorizontalAlignment="Left" Margin="12,41,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" />

ボタンのクリックイベントでは、以下のようにメッセージボックスを出すようにしました。

private void button1_Click(object sender, RoutedEventArgs e)
{
    // リソースからメッセージボックスの文字列をとってくる
    MessageBox.Show(Properties.Resources.MessageBoxText);
}

こちらは、App.xamlのResourcesに登録したインスタンスではなくて、staticなプロパティから値をとってきてます。


これで一応国際化対応で、日本語のカルチャーで実行されるとja-JPのリソースの文字列が使われて、それ以外のところでは英語になるのですが、あいにく日本語OSしかもってないので言語が切り替わるところが試せないので無理やりカルチャーを切り替えるようにボタンを2つ置いてクリックイベントで以下のように記述しました。

private void button2_Click(object sender, RoutedEventArgs e)
{
    // 英語化
    Properties.Resources.Culture = CultureInfo.GetCultureInfo("en-US");
    // Bindingを強制アップデート(動的にカルチャー切り替えない限りは必要ない)
    button1.GetBindingExpression(Button.ContentProperty).UpdateTarget();
}

private void button3_Click(object sender, RoutedEventArgs e)
{
    // 日本語化
    Properties.Resources.Culture = CultureInfo.GetCultureInfo("ja-JP");
    // Bindingを強制アップデート(動的にカルチャー切り替えない限りは必要ない)
    button1.GetBindingExpression(Button.ContentProperty).UpdateTarget();
}

カルチャーを切り替えた後で、ボタンのテキストを更新するために強引にバインドに対してUpdateTargetを呼び出しています。普通のアプリでは必要ないと思います。あくまで、今回のサンプルのためということで。


それでは実行してみます。とりあえず日本語。

f:id:okazuki:20110309234809j:image

英語化ボタンを押すと英語に。

f:id:okazuki:20110309234810j:image

プロジェクトのダウンロード

zigzagzoozigzagzoo 2011/08/31 12:03 いつもありがたく参考にさせていただいています。
WPFアプリケーションを作っていて、国際化対応したいと思っておりまして、
ズバリの記事に大変ありがたいのですが、
MVVMモデルでのアプリケーションにおいて、
OSの言語によって変わるだけであれば問題ないのですが、
ユーザが任意の言語を選択できるようにしたい場合、
どのような設計が考えられると思いますか?
もし、お知恵をお持ちでしたらお教えいただけたらと思います。

具体的なやりたいこととしては、

MVVMモデルに則ったアプリケーションにおいて、
Window内に複数のユーザコントロールを配置しており、
各ユーザコントロールの内部のコントロールの表示文字(Labelやbuttonの表示文字)を、
ComboboxやListViewなどのコントロールで言語を選択た言語で、
ResourceとBindingすることによって設定言語で表示したい。

どこで全てのコントロールのアップデートを行うのがいいのかを悩んでいます。

デザインパターンの、オブザーバーパターンのフレームワークを導入するのがいいのかな?
と思いますが、よくわかっていません。
ぜひ、ご教授ください。

okazukiokazuki 2011/09/04 10:30 > zigzagzooさん
コメントありがとうございます。
ちょっくら書いてみました。
http://d.hatena.ne.jp/okazuki/20110904/1315099747

これが一番いいやり方はどうかはわからないですが・・・。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/okazuki/20110309/1299683215