リムナンテスは愉快な気分

徒然なるままに、言語、数学、音楽、プログラミング、時々人生についての記事を書きます

C#(WPF)アプリ多言語対応の落とし穴と解決法

C#WPFアプリで多言語対応するためにリソースファイルを使おうと思ったのですが、いろんなところで躓いたので、解決策のメモです。
Visual Studio 2022です。

その1 リソースファイル/「Properties」フォルダ/「Resource」フォルダがない

プロジェクト作成直後のデフォルトの状態では、ソリューションエクスプローラーを見てもリソースファイル(.resx)や「Properties」フォルダ、「Resource」フォルダなどが見当たらないと思います。

プロジェクトを作成してデフォルトの状態ではリソースファイルが存在しません。そのため、プロジェクトのプロパティを開いてリソースファイルを作成します。
プロパティは、メニューバーの「プロジェクト」>「WpfApp1 のプロパティ」(例えば。WpfApp1のところは作成したプロジェクト名が入ります)で開きます。

「リソース」>「全般」の「アセンブリ リソースを作成する/開く」をクリックすることで、「Properties」フォルダと「Resources.resx」が作成され、ソリューションエクスプローラーに表示されます。

新しい言語のリソースファイルを追加する場合は、「Properties」フォルダを右クリック>「追加」>「新しい項目」でリソースファイルを追加できます。

その2 リソースの参照の仕方がわからない

XAML

その1のように、「Properties」フォルダにリソースファイル(.resx)が配置されているというディレクトリ構成であれば、Windowブロックにxmlns:properties="clr-namespace:WpfApp1.Properties"を挿入したうえで、

<Window x:Class="WpfApp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:properties="clr-namespace:WpfApp1.Properties"
        Title="MainWindow"
        Width="300"
        Height="100"
        mc:Ignorable="d">

多言語対応したい文字列のところを{x:Static properties:Resources.String1}に置き換えて書きます。この場合、UI上の表示は、該当言語のリソースファイルの「String1」に対応する値を参照して表示します。

例えばTextBlockのTextを置き換えるのであれば、

<TextBlock FontSize="20"
           Text="{x:Static properties:Resources.String1}" />
C#

String1の値を参照する場合は、Properties.Resources.String1のように書きます。
例えば、下記のようにするとメッセージボックスの文字列に使えます。

namespace MultiLangApp
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void ButtonText_Click(object sender, RoutedEventArgs e)
        {
            MessageBox.Show(Properties.Resources.String1);
        }
    }
}

その3 .xamlのプレビューが表示されない

一旦ビルドしましょう。ビルドに成功すれば表示されるようになります。

その4 ビルドするとエラーがでて成功しない

リソースファイルのアクセス修飾子を「Public」に変更しましょう。

リソースファイル(.rsax)を開きまして、上の方に「アクセス修飾子」があります。
デフォルトでは「Internal」になっているっぽいので、これを「Public」に変更すればビルドが通る。