WinUI3アプリをローカライズする(ResourceDictionary使用)

WInUI3関連記事
https://tera1707.com/entry/2022/02/06/144447#WinUI3

やりたいこと

WinUI3アプリをローカライズしたい。

以前の記事で、MSのドキュメントをもとに、.reswを使ってローカライズをした。

WinUI3を手探りで使う中でローカライズをしたいときに、MS公式にあるやり方で間違いないだろうということでそのやり方でやってみたが、使いづらい面も個人的にあった。
(x:Uidを使うところ。こちらでやったWPFでのローカライズのように、単なる文字列リソースとして扱えないのが、便利でもあるが面倒だなと感じた。)

そういう時に、下記の記事で、WPFではリソースディクショナリを使ってもローカライズできるということを知った。

nishy-software.com

同じやり方がWinUI3でもできるんじゃないか?と思ったので、やってみる。

結果

WinUI3でもできた。
が、それがMSの想定するやり方なのか?は、ぱっとドキュメントを見つけられなかった。

とりあえず、やったことをメモっておく。

前提

  • WinUI3
  • WindowsAppSDK 1.2.221109.1
  • .NET6
  • VisualStudio2022 17.4.3

やり方

はじめに

以前調べた、reswを使ったローカライズと、共通する手順も多いので、そちらも参照。

手順

このテンプレートを使って、WinUI3プロジェクト作成する。

パッケージプロジェクトに含まれているPackage.appxmanifestのコードを開いて、使う言語の設定を行う。

<Resources>
    <Resource Language="x-generate"/>
</Resources>

となっている部分を、

  <Resources>
    <Resource Language="ja-JP"/>
    <Resource Language="en-US"/>
  </Resources>

と直す。

下記のような感じで、プロジェクトの下に、en-USja-JPフォルダを作成する。

作ったフォルダの中に、リソースディクショナリをそれぞれ追加する。
フォルダを右クリック⇒追加⇒新しい項目、で、下図のリソースディクショナリを選んで追加する。

今回は「StringDictionary.xaml」という名前にした。

追加したリソースディクショナリを、画面のxamlから見えるようにするために、App.xamlに、リソースディクショナリを登録するコードを入れる。

App.xamlに、下記の「★ココ!★」の部分を追記する。

<Application
    x:Class="WinUI3ResTest.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:WinUI3ResTest">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
                <!-- Other merged dictionaries here -->
                <ResourceDictionary Source="StringDictionary.xaml"/> <!-- ★ココ!★ -->
            </ResourceDictionary.MergedDictionaries>
            <!-- Other app resources here -->
        </ResourceDictionary>
    </Application.Resources>
</Application>

リソースディクショナリに、ローカライズしたい文言を書く。

今回は、下記のようにした。

en-USフォルダの中のStringDictionary.xaml

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <x:String x:Key="TestString1">aiueo</x:String>
    <x:String x:Key="TestString2">kakikukeko</x:String>
</ResourceDictionary>

ja-JPフォルダの中のStringDictionary.xaml

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <x:String x:Key="TestString1">あいうえお</x:String>
    <x:String x:Key="TestString2">かきくけこ</x:String>
</ResourceDictionary>

※地味にハマったポイント

VisualStudioからリソースを追加した直後は、私の環境だと、StringDictionary.xamlSJISになっていて、これを使って画面表示させると、文字が化けて表示されてしまった。
それでは困るので、今回は手動(ほかのエディタを使って)UTF-8にしてやると、文字化けせずに表示された。

作ったリソースディクショナリを使う画面を作る。
今回は試しに下記のようにした。

<Window
    x:Class="WinUI3ResTest.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:WinUI3ResTest"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
        <Button x:Name="myButton" Click="myButton_Click" Content="{StaticResource TestString1}"></Button>
    </StackPanel>
</Window>

ボタンの中の文字が、リソースディクショナリに書いた文言になる想定。

日本語、英語で動かすと、下図のようになった。

英語

日本語

コードからリソースを取りたいとき

別記事で試したが、下記で取れる。
(今の言語に対応したリソースを取ってくれる)

            var rc = (string)Application.Current.Resources["TestString1"];
            Debug.WriteLine(rc);

余談

ローカライズの簡易テストのときに、WPFのときにコードに仕込んで言語を切り替えていた

CultureInfo.CurrentUICulture = new CultureInfo("ja-JP", false);

が、WinUI3のパッケージ版では効かなかった。
(実際にWindouwの言語設定を変えないと、言語が切り替わってくれなかった)

なにか違うのかも...

参考

以前調べた、reswを使ったローカライズ記事(WinUI3)

https://tera1707.com/entry/2022/03/24/224855

以前調べた、Propertiesを使ったローカライズ記事(WPF/.net Framework)

https://qiita.com/tera1707/items/fb6570f3894a607f9dce

以前調べた、ResourceDictionaryを使ったローカライズ記事(WPF)

https://tera1707.com/entry/2023/01/11/233227