WinUI 3 の多言語化
はじめに
WinUI 3 (Windows App SDK) には、OS の言語設定に合わせて表示言語を自動的に切り替える仕組みが標準で備わっており、.resw ファイルで言語リソースを用意すれば簡単に多言語化(ローカライズ)を実現できます。
やり方を順を追ってまとめました。
対応言語の宣言
Template Studio を使用している場合、多言語化のための準備は不要です。
Visual Studio でプロジェクト新規作成時、「WinUI の Template Studio」で作成することで、自動的に多言語化の準備が整います。

Template Studio を使わずに手動でイチからコードを書く場合は、Microsoft のサイトにあるように、package.appxmanifest に
<Resources>
    <Resource Language="en-US"/>
    <Resource Language="es-ES"/>
</Resources>
のように宣言します。
多言語化の第一歩
Template Studio でプロジェクトを作成すると、Strings\en-us フォルダーに Resources.resw ファイルが入っています。
en-us フォルダーごとコピーし、ja-jp フォルダーにします。

ja-jp フォルダーの Resources.resw を Visual Studio でダブルクリックして開くと編集できます。
AppDisplayName や Main_Title.Text の「値」に適当な日本語を入力します。

ビルドして日本語環境で実行すると、日本語で表示されます(日本語にならない場合は、リビルドないしはソリューションをクリーンします)。

OS の言語設定を英語にして、

実行すると英語で表示されます。

多言語化のやり方まとめ
XAML
XAML で記述する UI を多言語化したい場合は、対象となるコントロールに x:Uid 属性を付けます。
<Button x:Uid="MyButton" />
各言語の Resources.resw には、「x:Uid.プロパティー名」と翻訳のペアを記載します。
例えばボタンの場合は、
| 名前 | 値 | 
|---|---|
| MyButton.Content | クリックしてください | 
| MyButton.ToolTipService.ToolTip | このボタンをクリックすると、何か起こるかもしれません | 
のような感じです。

これだけで多言語化されます。
x:Uid 属性を指定したのに Resouces.resw に対応する翻訳ペアが存在しない場合、特にエラーにはなりません。
コード
プログラムコードで多言語化したい場合は、ResourceLoader を使用します。
using Microsoft.Windows.ApplicationModel.Resources;
ResourceLoader resourceLoader = new();
String message = resourceLoader.GetString("IdForCode");
ただし、Template Studio では便利な拡張メソッドが定義済のため、ResourceLoader の代わりに
String message = "IdForCode".GetLocalized();
とすることで簡単に翻訳を得られます。
各言語の Resources.resw には、GetString() の引数で渡す ID に対応した翻訳を記載します。
| 名前 | 値 | 
|---|---|
| IdForCode | コードで多言語化 | 
なお、Resources.resw に翻訳が定義されていない場合は実行時に例外が発生するので注意が必要です。
ms-resource
アプリケーション表示名など、ms-resource 表記が使える場所は、ms-resource:hoge のように記載します。

各言語の Resources.resw には、hoge と翻訳のペアを記載します。
| 名前 | 値 | 
|---|---|
| hoge | ほげ | 
翻訳の CSV 管理
WinUI 3 の多言語化は簡単ですが、以下の課題があると感じました。
- Resources.resw が言語ごとに分かれているため、
- 翻訳 ID("IdForCode")を言語ごとに書く必要があり手間が増える
- 翻訳漏れに気付きにくい(英語で定義した単語を日本語で定義し忘れるなど)
 
- 翻訳 ID を文字列で指定するため、スペルミスが発生する
そこで、翻訳を CSV 管理すると楽になるかなと思います。

- 1 行で複数言語の翻訳を書けるため、
- 言語が増えても翻訳 ID は 1 回書けば良い
- 翻訳漏れに気付きやすい
 
さらに、CSV を Google スプレッドシートなどのオンラインツールで作成すれば、複数名で翻訳作業を行うのも簡単です。
CSV から .resw を作成する CSV to resw を公開しています。

Strings フォルダーに CSV を置き、CSV to resw で変換することで、全言語の .resw を作成できます。
翻訳 ID を enum として出力するので、プログラムコードで翻訳を得る際に、
String message = Localize.MainPageViewModel_MessageContent.Localized();
のように入力しますが、入力途中で IntelliSense の助けを受けながら翻訳を取得することができるようになり、手間とミスが減ります。
確認環境
| 項目 | 環境 | 
|---|---|
| OS | Windows 11 Pro 23H2 / Windows 10 Pro 22H2 | 
| Visual Studio | 2022 17.9.5 | 
| Template Studio for WinUI | 5.5 | 
| .NET | 8.0 | 
| Windows App SDK | 1.5.1 (1.5.240311000) | 





Discussion