かずきのBlog@hatena

すきな言語は C# + XAML の組み合わせ。Azure Functions も好き。最近は Go 言語勉強中。日本マイクロソフトで働いていますが、ここに書いていることは個人的なメモなので会社の公式見解ではありません。

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

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

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

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

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

そして、このクラスを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のデザイナからさくっとできます。

いい世の中ですね。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を呼び出しています。普通のアプリでは必要ないと思います。あくまで、今回のサンプルのためということで。


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

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

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