ローカライズ
ローカライズは、ターゲット市場の特定の言語または文化の要件を満たすようにアプリケーションを適合させるプロセスです。 アプリをローカライズするには、テキストと画像を複数の言語に翻訳する必要がある場合があります。 ローカライズされたアプリでは、デバイスのカルチャ設定に基づいて、翻訳されたテキストが自動的に表示されます。
.NET には、resource files を使用してアプリをローカライズするための組み込みメカニズムが用意されています。 リソース ファイルには、指定されたキーのコンテンツをアプリケーションで取得できるように、テキストやその他のコンテンツが名前と値の組として格納されます。 リソース ファイルを使用すると、ローカライズされたコンテンツをアプリ コードから分離できます。 リソース ファイルには、テキストの格納に加えて、画像とバイナリ データを格納することもできます。 ただし、デバイスにはさまざまな画面サイズと密度があり、各プラットフォームには、密度に依存した画像を表示する機能があります。 そのため、画像をローカライズするには、リソース ファイルに画像を格納する代わりに、プラットフォームの機能を使用する必要があります。
.NET マルチプラットフォーム アプリ UI (.NET MAUI) アプリをローカライズするには、次の操作を行う必要があります。
- 文字列を格納するリソース ファイルを作成します。 詳細については、「文字列を格納するリソース ファイルを作成する」をご覧ください。
- アプリのニュートラル言語を指定する。 詳細については、「アプリのニュートラル言語を指定する」をご覧ください。
- プラットフォームのセットアップを実行します。 詳細については、「Perform platform setup」をご覧ください。
- テキストをローカライズします。 詳しくは、「テキストをローカライズする」をご覧ください。
- イメージをローカライズします。 詳細については、「イメージをローカライズする」をご覧ください。
- アプリ名をローカライズします。 詳細については、「アプリ名をローカライズする」をご覧ください。
- ローカライズをテストします。 詳細については、「ローカライズをテストする」をご覧ください。
さらに、アプリのレイアウト方向を指定できます。 詳細については、「Right to left localization」をご覧ください。
文字列を格納するリソース ファイルを作成する
リソース ファイルは、ビルド処理中にバイナリ リソース (.resources) ファイルにコンパイルされた、.resx 拡張子を持つ XML ファイルです。 ローカライズされたアプリには、通常、アプリで使用されるすべての文字列を含む既定のリソース ファイルとサポートされている各言語のリソース ファイルが含まれています。
リソース ファイルには、各項目に関する次の情報が含まれています。
- [名前] では、コード内のテキストへのアクセスに使用されるキーが指定されます。
- [値] では、翻訳済みテキストが指定されます。
- [コメント] は、追加情報を含む省略可能なフィールドです。
Visual Studio では、[新しい項目を追加する] ダイアログを使用してリソース ファイルを追加します。
ファイルが追加されると、各テキスト リソースに対して行を追加できるようになります。
[アクセス修飾子] ドロップダウンでは、リソースへのアクセスに使用されるクラスが Visual Studio でどのように生成されるかを決定します。 [アクセス修飾子] を [公開] または [内部] に設定すると、指定したアクセシビリティ レベルを持つクラスが生成されます。 [アクセス修飾子] を [コード生成なし] に設定すると、クラス ファイルは生成されません。 既定のリソース ファイルは、クラス ファイルを生成するように構成する必要があります。これにより、.designer.cs 拡張子を持つファイルがプロジェクトに追加されます。
既定のリソース ファイルが作成されたら、アプリでサポートされる追加のファイルを作成できます。 追加の各リソース ファイルには、既定のリソース ファイルと同じルート ファイル名が必要ですが、ファイル名には言語および省略可能なカルチャも含める必要があります。 たとえば、AppResources.resx という名前のリソース ファイルを追加する場合に、英語 (米国) とフランス語 (フランス) の各カルチャ用にローカライズされたリソースを保持するには、AppResources.en-US.resx と AppResources.fr-FR.resx という名前のリソース ファイルを作成します。 さらに、追加の各リソース ファイルの アクセス修飾子 を [コードの生成なし] に設定する必要があります。
実行時に、アプリではリソース要求を特異性の順に解決することが試行されます。 たとえば、デバイスのカルチャが en-US である場合、アプリケーションでは次の順序でリソース ファイルが検索されます。
- AppResources.en-US.resx
- AppResources.en.resx
- AppResources.resx (既定)
次のスクリーンショットは、AppResources.es.resx という名前のスペイン語の翻訳ファイルを示しています。
ローカライズされたリソース ファイルでは、既定のファイルで指定されているのと同じ [名前] 値が使用されますが、[値] 列にはスペイン語の文字列が含まれています。 また、[アクセス修飾子] は [コード生成なし] に設定されています。
アプリのニュートラル言語を指定する
.NET リソース ファイルが正常に機能するには、アプリにニュートラル言語が指定されている必要があります。 これは、ロケールのリソースが見つからない場合に使用されるリソースの言語です。 ニュートラル言語を指定するには、次の手順に従います。
ソリューション エクスプローラーで、.NET MAUI アプリ プロジェクトを右クリックし、[プロパティ] を選択します。
[パッケージ] > [全般] プロパティ ページを選択し、[アセンブリ ニュートラル言語] ドロップダウンから適切な言語とカルチャを選択します。
変更を保存。
または、プロジェクト ファイルの最初の <PropertyGroup>
に <NeutralLanguage>
要素を追加し、選択したロケールをその値として指定します。
<NeutralLanguage>en-US</NeutralLanguage>
警告
ニュートラル言語を指定しない場合、ResourceManager クラスは、リソース ファイルのない任意の言語の null
値を返します。 ニュートラル言語を指定すると、ResourceManager クラスは、サポートされていない言語のニュートラル言語リソース ファイルから結果を返します。 そのため、サポートされていない言語のテキストが表示されるように、常にニュートラル言語を指定することをお勧めします。
プラットフォームのセットアップを実行する
すべての .NET MAUI コントロールがローカライズされるように、iOS、Mac Catalyst、Windows で追加のセットアップを行う必要があります。
iOS と Mac Catalyst
iOS と Mac Catalyst では、.NET MAUI アプリ プロジェクトのプラットフォームの Info.plist ファイルで、サポートされているすべての言語を宣言する必要があります。 それには、選択したプラットフォームの Info.plist ファイルを XML エディターで開き、CFBundleLocalizations
キーの配列を作成します。 次に、リソース ファイルに対応する配列値を指定します。 さらに、CFBundleDevelopmentRegion
キーを使用して、予期される言語が設定されていることを確認します。
<key>CFBundleLocalizations</key>
<array>
<string>de</string>
<string>es</string>
<string>fr</string>
<string>ja</string>
<string>pt</string> <!-- Brazil -->
<string>pt-PT</string> <!-- Portugal -->
<string>ru</string>
<string>zh-Hans</string>
<string>zh-Hant</string>
</array>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
または、Visual Studio のソリューション エクスプローラーで、選択したプラットフォームの Info.plist ファイルを汎用 plist エディターで開きます。 次に、CFBundleLocalizations
キーの配列を作成し、リソース ファイルに対応する配列値を指定します。 さらに、CFBundleDevelopmentRegion
キーを使用して、予期される言語が設定されていることを確認します。
Info.plist ファイルの詳細については、「情報プロパティ リスト」をご覧ください。
Windows
Windows 版の .NET MAUI アプリで複数の言語をサポートするには、サポートされている各言語を .NET MAUI アプリ プロジェクトの Platforms\Windows\Package.appxmanifest ファイルで宣言する必要があります。
Package.appxmanifest ファイルをテキスト エディターで開き、次のセクションを見つけます。
<Resources> <Resource Language="x-generate"/> </Resources>
<Resource Language="x-generate">
を、サポートされている各言語の<Resource />
要素に置き換えます。<Resources> <Resource Language="en-US"/> <Resource Language="de-DE"/> <Resource Language="es-ES"/> <Resource Language="fr-FR"/> <Resource Language="ja-JP"/> <Resource Language="pt-BR"/> <Resource Language="pt-PT"/> <Resource Language="ru-RU"/> <Resource Language="zh-CN"/> <Resource Language="zh-TW"/> </Resources>
変更を保存。
テキストをローカライズする
テキストは、既定のリソース ファイルから生成されたクラスを使用してローカライズされます。 このクラスには、既定のリソース ファイル名に基づいて名前が付けられます。 AppResources.resx の既定のリソース ファイル名が指定される場合、リソース ファイル内の各エントリの静的プロパティを含んだ、AppResources
という名前の対応するクラスが Visual Studio によって生成されます。
XAML では、x:Static
マークアップ拡張を使用して、生成された静的プロパティにアクセスすることで、ローカライズされたテキストを取得できます。
<ContentPage ...
xmlns:strings="clr-namespace:LocalizationDemo.Resources.Strings">
<VerticalStackLayout>
<Label Text="{x:Static strings:AppResources.NotesLabel}" />
<Entry Placeholder="{x:Static strings:AppResources.NotesPlaceholder}" />
<Button Text="{x:Static strings:AppResources.AddButton}" />
</VerticalStackLayout>
</ContentPage>
x:Static
マークアップ拡張機能の詳細については、「x: 静的マークアップ拡張機能」をご覧ください。
ローカライズされたテキストは、次のようにコードで取得することもできます。
Label notesLabel = new Label();
notesLabel.Text = AppResources.NotesLabel,
Entry notesEntry = new Entry();
notesEntry.Placeholder = AppResources.NotesPlaceholder,
Button addButton = new Button();
addButton.Text = AppResources.AddButton,
AppResources
クラスのプロパティでは、CurrentUICulture プロパティ値を使用して、どのリソース ファイルから値を取得するかを決定します。
イメージをローカライズする
リソース ファイルには、テキストの格納に加えて、画像とバイナリ データを格納することもできます。 ただし、デバイスにはさまざまな画面サイズと密度があり、各プラットフォームには、密度に依存した画像を表示する機能があります。 そのため、画像をローカライズするには、リソース ファイルに画像を格納する代わりに、プラットフォームの機能を使用する必要があります。
Android
Android では、ドローアブルとも呼ばれるローカライズされた画像が、フォルダーベースの名前付け規則に従って Platforms\Android\Resources フォルダーに格納されます。 フォルダーは、drawable に言語とカルチャのサフィックスが付いた名前になります。 たとえば、スペイン語の言語のフォルダーには drawable-es という名前が付けられます。 drawable という名前のフォルダーには、既定の言語とカルチャの画像が含まれています。 各イメージのビルド アクションを AndroidResource に設定する必要があります。
Note
個々のファイルを AndroidResource ビルド アクションに設定するのではなく、アプリのプロジェクト (.csproj) ファイルに次の XML を追加することで、特定のフォルダーの内容をこのビルド アクションに設定できます。
<ItemGroup Condition="$(TargetFramework.Contains('-android'))">
<AndroidResource Include="Platforms\Android\Resources\**" TargetPath="%(RecursiveDir)%(Filename)%(Extension)" />
</ItemGroup>
次の使用例は、サブフォルダー内のコンテンツを含む Platforms\Android\Resources フォルダー内のすべてのコンテンツを AndroidResource ビルド アクションに設定します。 また、このビルド アクションを使用して各ファイルの出力パスを設定します。
最上位言語 (es など) を指定する場合、フォルダー名には 2 文字のみが必要です。 ただし、完全なロケールを指定する場合、言語をカルチャから分離するために、フォルダー名の形式にはダッシュと小文字の r が必要です。 たとえば、メキシコ ロケール (es-MX) フォルダーには、drawable-es-rMX という名前を付ける必要があります。 各ロケール フォルダー内のイメージ ファイル名は同じである必要があります。
iOS
iOS の場合、ローカライズされたイメージは、Platforms\iOS\Resources 内のフォルダーに、フォルダーベースの名前付け規則を使用して格納されます。 フォルダーには言語と省略可能なカルチャを使用して名前を付け、その後に .lproj を付ける必要があります。 たとえば、スペイン語のフォルダーには es.lproj という名前が付けられます。 各イメージのビルド アクションを BundleResource に設定する必要があります。
Note
個々のファイルを BundleResource ビルド アクションに設定するのではなく、アプリのプロジェクト (.csproj) ファイルに次の XML を追加することで、特定のフォルダーの内容をこのビルド アクションに設定できます。
<ItemGroup Condition="$(TargetFramework.Contains('-ios'))">
<BundleResource Include="Platforms\iOS\Resources\**" TargetPath="%(RecursiveDir)%(Filename)%(Extension)" />
</ItemGroup>
次の例では、サブフォルダー内のコンテンツを含む Platforms\iOS\Resources フォルダー内のすべてのコンテンツを BundleResource ビルド アクションに設定しています。 また、このビルド アクションを使用して各ファイルの出力パスを設定します。
最上位言語 (es など) を指定する場合、フォルダー名には 2 文字のみが必要です。 ただし、完全なロケールを指定する場合、フォルダー名の形式には、カルチャから言語を分離するためのダッシュが必要です。 たとえば、メキシコ ロケール (es-MX) フォルダーには、es-MX.lproj という名前を付ける必要があります。 各ロケール フォルダー内のイメージ ファイル名は同じである必要があります。
特定の言語にイメージが存在しない場合、iOS は既定のネイティブ言語フォルダーにフォールバックし、そこからイメージを読み込みます。
Mac Catalyst
Mac Catalyst では、ローカライズされたイメージは、Platforms\MacCatalyst\Resources フォルダー内のフォルダーベースの名前付け規則を使用して格納されます。 フォルダーには言語と省略可能なカルチャを使用して名前を付け、その後に .lproj を付ける必要があります。 たとえば、スペイン語のフォルダーには es.lproj という名前が付けられます。 各イメージのビルド アクションを BundleResource に設定する必要があります。
Note
個々のファイルを BundleResource ビルド アクションに設定するのではなく、アプリのプロジェクト (.csproj) ファイルに次の XML を追加することで、特定のフォルダーの内容をこのビルド アクションに設定できます。
<ItemGroup Condition="$(TargetFramework.Contains('-maccatalyst'))">
<BundleResource Include="Platforms\MacCatalyst\Resources\**" TargetPath="%(RecursiveDir)%(Filename)%(Extension)" />
</ItemGroup>
次の使用例は、サブフォルダー内のコンテンツを含む Platforms\MacCatalyst\Resources フォルダー内のすべてのコンテンツを BundleResource ビルド アクションに設定します。 また、このビルド アクションを使用して各ファイルの出力パスを設定します。
最上位言語 (es など) を指定する場合、フォルダー名には 2 文字のみが必要です。 ただし、完全なロケールを指定する場合、フォルダー名の形式には、カルチャから言語を分離するためのダッシュが必要です。 たとえば、メキシコ ロケール (es-MX) フォルダーには、es-MX.lproj という名前を付ける必要があります。 各ロケール フォルダー内のイメージ ファイル名は同じである必要があります。
特定の言語のイメージが存在しない場合、Mac Catalyst は、既定のネイティブ言語フォルダーにフォールバックし、そこからイメージを読み込みます。
Windows
Windows の場合、ローカライズされたイメージは、Platforms\Windows\Assets\Images フォルダー内に、フォルダーベースの名前付け規則を使用して格納されます。 フォルダーには、言語と省略可能なカルチャを使用して名前を付ける必要があります。 たとえば、スペイン語のフォルダーには es、メキシコ ロケール フォルダーには es-MX という名前を付ける必要があります。 各イメージのビルド アクションをコンテンツtに設定する必要があります。
Note
個々のファイルをコンテンツ ビルド アクションに設定するのではなく、アプリのプロジェクト (.csproj) ファイルに次の XML を追加することで、特定のフォルダーのコンテンツをこのビルド アクションに設定できます。
<ItemGroup Condition="$(TargetFramework.Contains('-windows'))">
<Content Include="Platforms\Windows\Assets\Images\**" TargetPath="%(RecursiveDir)%(Filename)%(Extension)" />
</ItemGroup>
次の例では、サブフォルダー内のコンテンツを含むPlatforms\Windows\Assets\Images フォルダー内のコンテンツをコンテンツ ビルド アクションに設定しています。 また、このビルド アクションを使用して各ファイルの出力パスを設定します。
最上位言語 (es など) を指定する場合、フォルダー名には 2 文字のみが必要です。 ただし、完全なロケールを指定する場合、フォルダー名の形式には、カルチャから言語を分離するためのダッシュが必要です。 たとえば、メキシコ ロケール (es-MX) フォルダーには、es-MX という名前を付ける必要があります。 各ロケール フォルダー内のイメージ ファイル名は同じである必要があります。
ローカライズされたイメージを使用する
Android、iOS、Mac Catalyst、Windows では、Image の Source プロパティをイメージ ファイル名に設定し、ローカライズされたイメージを使用できます。
<Image Source="flag.png" />
ただし、ローカライズされたイメージごとに <Content />
MSBuild 項目を追加している場合、Windows でこれを機能させるには、アプリのプロジェクト ファイルを変更する必要があります。 これは、.csproj ファイルを修正して、各イメージの <Content />
MSBuild 項目を削除することで実現できます。 次に、次の MSBuild 項目を追加します。
<ItemGroup Condition="$(TargetFramework.Contains('-windows'))">
<Content Include="Platforms\Windows\Assets\Images\**" TargetPath="%(RecursiveDir)%(Filename)%(Extension)" />
</ItemGroup>
これにより、Platforms\Windows\Assets\Images フォルダーのサブフォルダー内のすべてのイメージがアプリ パッケージのルートにコピーされます。
アプリ名をローカライズする
プラットフォーム機能は、アプリの名前をローカライズするために必要です。
Android
Android では、ローカライズされたアプリ名は、Platforms\Android\Resources フォルダー内のフォルダー ベースの名前付け規則を使用して格納できます。 フォルダー名には、言語とカルチャのサフィックス付きの 値 を付ける必要があります。 たとえば、スペイン語のフォルダーには values-es という名前が付けられます。 AndroidResource のビルド アクションを含む Strings.xml ファイルを、ローカライズされたアプリ名に文字列を設定する各フォルダーに追加します。
Note
個々のファイルを AndroidResource ビルド アクションに設定するのではなく、アプリのプロジェクト (.csproj) ファイルに次の XML を追加することで、特定のフォルダーの内容をこのビルド アクションに設定できます。
<ItemGroup Condition="$(TargetFramework.Contains('-android'))">
<AndroidResource Include="Platforms\Android\Resources\**" TargetPath="%(RecursiveDir)%(Filename)%(Extension)" />
</ItemGroup>
次の使用例は、サブフォルダー内のコンテンツを含む Platforms\Android\Resources フォルダー内のすべてのコンテンツを AndroidResource ビルド アクションに設定します。 また、このビルド アクションを使用して各ファイルの出力パスを設定します。
最上位言語 (es など) を指定する場合、フォルダー名には 2 文字のみが必要です。 ただし、完全なロケールを指定する場合、言語をカルチャから分離するために、フォルダー名の形式にはダッシュと小文字の r が必要です。 たとえば、メキシコ ロケール (es-MX) フォルダーには、values-es-rMX という名前を付ける必要があります。
変換可能な各文字列は、リソース ID が name
属性として指定され、変換された文字列が値として指定された XML 要素です。 通常の XML 規則に従って文字列をエスケープする必要があり、name
は有効な Android リソース ID (スペースやダッシュなし) である必要があります。
そのため、アプリ名をローカライズするには、Strings.xml ファイルを作成し、<resources>
要素の子として <string>
要素を追加します。 次に、その name
属性を翻訳された文字列を値として、適切な ID に設定します。
<resources>
<!-- French -->
<string name="app_name">Maison</string>
</resources>
次に、アプリでローカライズされたアプリ名を使用するには、アプリの MainActivity
クラスの Activity
に Label
プロパティを追加し、その値を @string/id
に設定します。
[Activity(Label = "@string/app_name", Theme = "@style/Maui.SplashTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize | ConfigChanges.Density)]
public class MainActivity : MauiAppCompatActivity
{
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
}
}
iOS
iOS では、ローカライズされたアプリ名は、フォルダーベースの名前付け規則に従って Platforms\iOS\Resources フォルダー内に格納されます。 フォルダーには言語と省略可能なカルチャを使用して名前を付け、その後に .lproj を付ける必要があります。 たとえば、スペイン語のフォルダーには es.lproj という名前が付けられます。 BundleResource のビルド アクションを含む InfoPlist.strings ファイルを、CFBundleDisplayName
キーと値を設定する各フォルダーに追加します。
Note
個々のファイルを BundleResource ビルド アクションに設定するのではなく、アプリのプロジェクト (.csproj) ファイルに次の XML を追加することで、特定のフォルダーの内容をこのビルド アクションに設定できます。
<ItemGroup Condition="$(TargetFramework.Contains('-ios'))">
<BundleResource Include="Platforms\iOS\Resources\**" TargetPath="%(RecursiveDir)%(Filename)%(Extension)" />
</ItemGroup>
次の例では、サブフォルダー内のコンテンツを含む Platforms\iOS\Resources フォルダー内のすべてのコンテンツを BundleResource ビルド アクションに設定しています。 また、このビルド アクションを使用して各ファイルの出力パスを設定します。
ローカライズされた文字列値の構文は次のとおりです。
/* comment */
"key"="localized-value";
文字列内の次の文字をエスケープする必要があります。
\"
のクォート\\
バックスラッシュ\n
改行
そのため、アプリ名をローカライズするには、InfoPlist.strings ファイルを作成し、CFBundleDisplayName
キーの値をファイルに追加します。
/* French */
CFBundleDisplayName="Maisons";
アプリ固有の文字列をローカライズするために使用できるその他のキーは次のとおりです。
CFBundleName
: アプリ バンドルの短い名前を指定します。この名前は、CFBundleDisplayName
の値が存在しないなどの状況でユーザーに表示される場合があります。CFBundleShortVersionString
: アプリ バンドルのリリース バージョン番号を指定します。NSHumanReadableCopyright
: アプリ バンドルの著作権に関する通知。
Mac Catalyst
Mac Catalyst では、ローカライズされたアプリ名は、フォルダーベースの名前付け規則に従って Platforms\MacCatalyst\Resources フォルダー内に格納されます フォルダーには言語と省略可能なカルチャを使用して名前を付け、その後に .lproj を付ける必要があります。 たとえば、スペイン語のフォルダーには es.lproj という名前が付けられます。 BundleResource のビルド アクションを含む InfoPlist.strings ファイルを、CFBundleDisplayName
キーと値を設定する各フォルダーに追加します。
Note
個々のファイルを BundleResource ビルド アクションに設定するのではなく、アプリのプロジェクト (.csproj) ファイルに次の XML を追加することで、特定のフォルダーの内容をこのビルド アクションに設定できます。
<ItemGroup Condition="$(TargetFramework.Contains('-maccatalyst'))">
<BundleResource Include="Platforms\MacCatalyst\Resources\**" TargetPath="%(RecursiveDir)%(Filename)%(Extension)" />
</ItemGroup>
次の使用例は、サブフォルダー内のコンテンツを含む Platforms\MacCatalyst\Resources フォルダー内のすべてのコンテンツを BundleResource ビルド アクションに設定します。 また、このビルド アクションを使用して各ファイルの出力パスを設定します。
ローカライズされた文字列値の構文は次のとおりです。
/* comment */
"key"="localized-value";
文字列内の次の文字をエスケープする必要があります。
\"
のクォート\\
バックスラッシュ\n
改行
そのため、アプリ名をローカライズするには、InfoPlist.strings ファイルを作成し、CFBundleDisplayName
キーの値をファイルに追加します。
/* French */
CFBundleDisplayName="Maisons";
アプリ固有の文字列をローカライズするために使用できるその他のキーは次のとおりです。
CFBundleName
: アプリ バンドルの短い名前を指定します。これは、CFBundleDisplayName
値が存在しないなどの状況でユーザーに表示される可能性があります。CFBundleShortVersionString
: アプリ バンドルのリリース バージョン番号を指定します。NSHumanReadableCopyright
: アプリ バンドルの著作権に関する通知。
Windows
Windows では、アプリ名はアプリ パッケージ マニフェストで定義されます。 アプリ名をローカライズするには、まずアプリの既定の言語を指定してから、サポートするロケールごとに文字列リソース ファイルを作成する必要があります。 ローカライズされたアプリ名を表す文字列リソースは、ms-resource
URI スキームを使用してアプリ パッケージ マニフェストで使用できます。
アプリ パッケージ マニフェストで文字列をローカライズする方法の詳細については、「UI とアプリ パッケージ マニフェスト内の文字列をローカライズする」をご覧ください。
既定の言語を指定する
アプリ名をローカライズするには、まず Windows アプリに既定の言語が指定されている必要があります。 これは、特定の言語用にローカライズされたリソースが見つからない場合にそのリソースが使用される言語です。 既定の言語を指定するには:
[ソリューション エクスプローラー] で、Package.appxmanifest ファイルをパッケージ マニフェスト エディターで開きます。
パッケージ マニフェスト エディターの [アプリケーション] タブで、[既定の言語] フィールドを選択した既定の言語に設定します。
変更を保存。
少なくとも、既定の言語のアプリ名の文字列リソースを指定する必要があります。 これは、ユーザーの優先言語または表示言語の設定に適した一致が見つからない場合に読み込まれるリソースです。
Windows リソース ファイルを作成する
Windows では、ローカライズされたアプリ名をロケールごとに Windows リソース ファイルに格納する必要があります。 Windows リソース ファイルは、バイナリ形式にコンパイルされ、.pri ファイルに格納される .resw 拡張子を持つ XML ファイルです。 各ロケールの .resw ファイルには Resources.resw という名前を付け、Platforms\Windows\Strings フォルダーにフォルダー ベースの名前付け規則を使用して格納する必要があります。 フォルダーには、言語と省略可能なカルチャを使用して名前を付ける必要があります。 たとえば、スペイン語のフォルダーには es、メキシコ ロケール フォルダーには es-MX という名前を付ける必要があります。
現在、.NET MAUI アプリで Windows リソース ファイルを作成するための Visual Studio 項目テンプレートはありません。 したがって、ロケールごとに Windows リソース ファイルを作成するには、次のようにします。
.NET MAUI アプリ プロジェクトの Platforms\Windows フォルダーに、Strings フォルダーを作成します。
Strings フォルダーで、ロケールごとにフォルダーを作成します。
各ロケールのフォルダーに、次の XML を含む Resources.resw という名前のファイルを作成します。
<?xml version="1.0" encoding="utf-8"?> <root> <!-- Microsoft ResX Schema Version 2.0 The primary goals of this format is to allow a simple XML format that is mostly human readable. The generation and parsing of the various data types are done through the TypeConverter classes associated with the data types. Example: ... ado.net/XML headers & schema ... <resheader name="resmimetype">text/microsoft-resx</resheader> <resheader name="version">2.0</resheader> <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> <value>[base64 mime encoded serialized .NET Framework object]</value> </data> <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> <comment>This is a comment</comment> </data> There are any number of "resheader" rows that contain simple name/value pairs. Each data row contains a name, and value. The row also contains a type or mimetype. Type corresponds to a .NET class that support text/value conversion through the TypeConverter architecture. Classes that don't support this are serialized and stored with the mimetype set. The mimetype is used for serialized objects, and tells the ResXResourceReader how to depersist the object. This is currently not extensible. For a given mimetype the value must be set accordingly: Note - application/x-microsoft.net.object.binary.base64 is the format that the ResXResourceWriter will generate, however the reader can read any of the formats listed below. mimetype: application/x-microsoft.net.object.binary.base64 value : The object must be serialized with : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter : and then encoded with base64 encoding. mimetype: application/x-microsoft.net.object.soap.base64 value : The object must be serialized with : System.Runtime.Serialization.Formatters.Soap.SoapFormatter : and then encoded with base64 encoding. mimetype: application/x-microsoft.net.object.bytearray.base64 value : The object must be serialized into a byte array : using a System.ComponentModel.TypeConverter : and then encoded with base64 encoding. --> <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> <xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> <xsd:element name="root" msdata:IsDataSet="true"> <xsd:complexType> <xsd:choice maxOccurs="unbounded"> <xsd:element name="metadata"> <xsd:complexType> <xsd:sequence> <xsd:element name="value" type="xsd:string" minOccurs="0" /> </xsd:sequence> <xsd:attribute name="name" use="required" type="xsd:string" /> <xsd:attribute name="type" type="xsd:string" /> <xsd:attribute name="mimetype" type="xsd:string" /> <xsd:attribute ref="xml:space" /> </xsd:complexType> </xsd:element> <xsd:element name="assembly"> <xsd:complexType> <xsd:attribute name="alias" type="xsd:string" /> <xsd:attribute name="name" type="xsd:string" /> </xsd:complexType> </xsd:element> <xsd:element name="data"> <xsd:complexType> <xsd:sequence> <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> </xsd:sequence> <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> <xsd:attribute ref="xml:space" /> </xsd:complexType> </xsd:element> <xsd:element name="resheader"> <xsd:complexType> <xsd:sequence> <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> </xsd:sequence> <xsd:attribute name="name" type="xsd:string" use="required" /> </xsd:complexType> </xsd:element> </xsd:choice> </xsd:complexType> </xsd:element> </xsd:schema> <resheader name="resmimetype"> <value>text/microsoft-resx</value> </resheader> <resheader name="version"> <value>2.0</value> </resheader> <resheader name="reader"> <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> </resheader> <resheader name="writer"> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> </resheader> </root>
Note
Windows リソース ファイルでは、
PRIResource
のビルド アクションが使用されます。 このビルド アクションは暗黙的に適用されるため、.NET MAUI アプリ内の各 .resw ファイルに設定する必要はありません。各 Resources.resw ファイルを開き、アプリの名前を表す文字列リソースを追加します。
Note
リソース識別子では大文字と小文字が区別されず、リソース ファイルごとに一意である必要があります。
各 Windows リソース ファイルを保存します。
次のスクリーンショットに、必要なフォルダーとファイル構造の例を示します。
ローカライズされたアプリ名を使用する
ローカライズされたアプリ名を表す文字列リソースを使用するには、ms-resource
URI スキームを使用します。
[ソリューション エクスプローラー] で、Package.appxmanifest ファイルをパッケージ マニフェスト エディターで開きます。
パッケージ マニフェスト エディターの [アプリケーション] タブで、"表示名" フィールドを、
ms-resource:
の後にアプリ名を識別する文字列リソースの名前を付けたものに設定します。変更を保存します。
重要
.resw ファイルが .NET MAUI アプリ プロジェクトとは別のアセンブリに格納されている場合は、リソース名への完全修飾パスを指定する必要があります。 ms-resource:Assembly/ResourceFilename/Resource
の形式が使用されます。
右から左へのローカライズ
フロー方向またはレイアウト方向とは、ページ上の UI 要素を視覚でスキャンしていく方向のことです。 アラビア語やヘブライ語などの一部の言語では、UI 要素が右から左へのフロー方向で配置される必要があります。 .NET MAUI アプリは、選択された言語とリージョンに基づいて、デバイスのフロー方向に自動的に従います。 ロケールに基づいてデバイスのフロー方向を取得する方法については、「Get the layout direction」をご覧ください。
アプリのフロー方向をオーバーライドするには、Window.FlowDirection プロパティを設定します。 または、要素ごとに VisualElement.FlowDirection プロパティを設定します。 これらのプロパティは、レイアウトを制御する親要素内での UI 要素のフロー方向を取得または設定するので、FlowDirection 列挙値の 1 つに設定する必要があります。
LeftToRight
RightToLeft
MatchParent
要素の FlowDirection プロパティを RightToLeft
に設定すると、配置が右に、読む順が右から左に、コントロールのレイアウトが右から左に設定されます。
警告
実行時に FlowDirection プロパティを変更すると、パフォーマンスに影響を与える負荷の高いレイアウト プロセスが発生します。
FlowDirection のプロパティの既定値は、MatchParent
です。 そのため、要素ではビジュアル ツリー内の親から FlowDirection
プロパティ値を継承し、任意の要素でその親から取得した値をオーバーライドできます。
ヒント
フロー方向を変更する必要がある場合は、ウィンドウ、ページ、またはルート レイアウトで FlowDirection プロパティを設定します。 これにより、アプリ、ページ、またはルート レイアウトに含まれるすべての要素が、フロー方向に適切に対応するようになります。
プラットフォームの設定
特定のプラットフォームの設定では、右から左のロケールを有効にする必要があります。
Android
.NET MAUI アプリ プロジェクト テンプレートを使用して作成されたアプリでは、右から左へのロケールを自動的にサポートしています。 このサポートは、アプリの AndroidManifest.xml ファイルの <application>
ノードで android:supportsRtl
属性を true
に設定することで有効になります。
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application ... android:supportsRtl="true" />
...
</manifest>
その後、右から左への言語を使用するようにデバイスやエミュレーターを変更することで、右から左へのローカライズをテストできます。 または、設定アプリで開発者向けオプションをアクティブにしている場合は、[設定] > [開発者向けオプション] で [右から左へのレイアウトを強制する] を有効にすることができます。 開発者向けオプションの構成については、developer.android.com で「デバイスの開発者向けオプションを設定する」をご覧ください。
iOS と Mac Catalyst
Info.plist の CFBundleLocalizations
キー用の配列項目に対してサポートされる言語として、必要な右から左のロケールを追加する必要があります。 次の例では、CFBundleLocalizations
キーの配列に追加されているアラビア語を示しています。
<key>CFBundleLocalizations</key>
<array>
<string>en</string>
<string>ar</string>
</array>
その後、デバイスまたはシミュレーター上の言語とリージョンを、Info.plist で指定された右から左のロケールに変更することで、右から左へのローカライズをテストできます。
Windows
必要な言語リソースは、Package.appxmanifest ファイルの <Resources>
ノードで指定する必要があります。 <Resource Language="x-generate">
要素を、サポートされている各言語の <Resource />
要素に置き換えます。 たとえば、次のマークアップでは、"en" と "ar" のローカライズされたリソースが使用可能であることを指定します。
<Resources>
<Resource Language="en" />
<Resource Language="ar" />
</Resources>
右から左へのローカライズは、デバイス上の言語とリージョンを適切な右から左のロケールに変更するこでテストできます。
ローカライズをテストする
実行時に、アプリは、CurrentUICulture プロパティで指定されたカルチャに基づいて、ローカライズされた適切なリソースをスレッドごとに読み込みます。
ローカライズをテストするには、各デバイスの設定アプリでデバイスの言語を変更することをお勧めします。
警告
コードで CurrentUICulture の値を設定することはできますが、その結果の動作がプラットフォーム間で一貫しないので、テストにはお勧めしません。
.NET MAUI