Локализация
Локализация — это процесс адаптации приложения в соответствии с конкретным языком или культурными требованиями целевого рынка. Чтобы локализовать приложение, его текст и изображения могут быть переведены на несколько языков. Локализованное приложение автоматически отображает переведенный текст на основе параметров языка и региональных параметров устройства.
.NET включает механизм локализации приложений с помощью файлов ресурсов. Файл ресурсов сохраняет текст и другое содержимое в виде пар "имя-значение", которые позволяют приложению получать содержимое для предоставленного ключа. Файлы ресурсов позволяют отделять локализованное содержимое от кода приложения. Помимо хранения текста файлы ресурсов также могут хранить изображения и двоичные данные. Однако устройства имеют диапазон размеров экрана и плотностей, а каждая платформа имеет функции для отображения изображений, зависящих от плотности. Таким образом, функции платформы следует использовать для локализации образов вместо хранения их в файлах ресурсов.
Чтобы локализовать многоплатформенный пользовательский интерфейс приложения .NET (.NET MAUI), необходимо выполнить следующие действия.
- Создайте файлы ресурсов для хранения строк. Дополнительные сведения см. в статье "Создание файлов ресурсов для хранения строк".
- Укажите нейтральный язык приложения. Дополнительные сведения см. в разделе "Указание нейтрального языка приложения".
- Выполните настройку платформы. Дополнительные сведения см. в разделе "Выполнение настройки платформы".
- Локализация текста. Дополнительные сведения см. в разделе "Локализация текста".
- Локализация изображений. Дополнительные сведения см. в разделе "Локализация изображений".
- Локализация имени приложения. Дополнительные сведения см. в разделе "Локализация имени приложения".
- Тестирование локализации. Дополнительные сведения см. в разделе "Тестирование локализации".
Кроме того, можно указать направление макета приложения. Дополнительные сведения см. в разделе "Справа налево" локализации.
Создание файлов ресурсов для хранения строк
Файлы ресурсов .NET — это XML-файлы с расширением RESX , скомпилированные в файлы двоичных ресурсов (.resources) во время процесса сборки. Локализованное приложение обычно содержит файл ресурсов по умолчанию со всеми строками, используемыми в приложении, и файлами ресурсов для каждого поддерживаемого языка.
Файлы ресурсов содержат следующие сведения для каждого элемента:
- Name (Имя) — ключ, используемый для доступа к тексту в коде;
- Value (Значение) — переведенный текст;
- Comment (Примечание) — необязательное поле, содержащее дополнительные сведения.
Файл ресурса можно добавить с помощью диалогового окна "Добавление нового элемента " в Visual Studio:
После добавления файла можно добавить строки для каждого текстового ресурса.
Раскрывающийся список модификатора Access определяет, как Visual Studio создает класс, используемый для доступа к ресурсам. Если выбрать общедоступный или внутренний модификатор доступа, будет создан класс с соответствующим уровнем доступности. Если для модификатора Access задано значение "Без создания кода", файл класса не создается. Файл ресурсов по умолчанию должен быть настроен для создания файла класса, который приводит к тому, что файл будет иметь значение . Расширение Designer.cs , добавляемое в проект.
После создания файла ресурсов по умолчанию можно создать дополнительные файлы для каждого языкового стандарта, который поддерживает приложение. Каждый дополнительный файл ресурсов должен иметь то же имя корневого файла, что и файл ресурсов по умолчанию, но также должен включать язык и необязательный язык и региональные параметры в имя файла. Например, если добавить файл ресурсов с именем AppResources.resx, можно также создать файлы ресурсов с именем AppResources.en-US.resx и AppResources.fr-FR.resx для хранения локализованных ресурсов для языковых параметров английского языка (США) и французского языка (Франция) соответственно. Кроме того, необходимо задать модификатор Access для каждого дополнительного файла ресурсов без создания кода.
Во время выполнения приложение пытается разрешить запрос ресурсов в порядке конкретности. Например, если на устройстве выбраны язык и региональные параметры ru-RU, приложение ищет файлы ресурсов в следующем порядке:
- AppResources.ru-RU.resx
- AppResources.ru.resx
- AppResources.resx (по умолчанию)
На следующем снимке экрана показан файл с переводом на испанский язык, который называется AppResources.es.resx:
Локализованный файл ресурсов использует те же значения name , которые указаны в файле по умолчанию, но содержат строки испанского языка в столбце Value . Кроме того, выбран модификатор доступаБез создания кода.
Указание нейтрального языка приложения
Чтобы файлы ресурсов .NET работали правильно, приложение должно иметь нейтральный язык. Это язык, ресурсы которого используются, если ресурсы для языкового стандарта не удается найти. Чтобы указать нейтральный язык, выполните указанные ниже действия.
В Обозреватель решений щелкните правой кнопкой мыши проект приложения .NET MAUI и выберите "Свойства".
Выберите страницу свойств "Общие пакеты>" и выберите соответствующий язык и региональные параметры в раскрывающемся списке "Нейтральный язык сборки":
Сохранение изменений.
Кроме того, добавьте <NeutralLanguage>
элемент в первый <PropertyGroup>
в файле проекта и укажите выбранный языковой стандарт в качестве значения:
<NeutralLanguage>en-US</NeutralLanguage>
Предупреждение
Если указать нейтральный язык, ResourceManager класс возвращает null
значения для всех языков без файла ресурса. При указании ResourceManager нейтрального языка класс возвращает результаты из файла ресурсов нейтрального языка для неподдерживаемых языков. Поэтому рекомендуется всегда указывать нейтральный язык, чтобы текст отображался для неподдерживаемых языков.
Настройка платформы
Дополнительная настройка необходима в iOS, Mac Catalyst и Windows, чтобы все элементы управления MAUI .NET были локализованы.
IOS и Mac Catalyst
В iOS и Mac Catalyst необходимо объявить все поддерживаемые языки в файле Info.plist платформы в проекте приложения .NET MAUI. Для этого откройте файл 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 см. в списке свойств Information.
Windows
Чтобы поддерживать несколько языков в приложении .NET MAUI в Windows, необходимо объявить каждый поддерживаемый язык в файле Platform\Windows\Package.appxmanifest проекта приложения .NET MAUI:
Откройте файл Package.appxmanifest в текстовом редакторе и найдите следующий раздел:
<Resources> <Resource Language="x-generate"/> </Resources>
<Resource />
Замените<Resource Language="x-generate">
элементами для каждого поддерживаемого языка:<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, Visual Studio создает соответствующий класс, AppResources
содержащий статические свойства для каждой записи в файле ресурса.
В 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:Static Markup extension.
Локализованный текст также можно извлекать в коде:
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 локализованные изображения, известные как рисуемые, хранятся с помощью соглашения об именовании на основе папок в папке Platform\Android\Resources . Папки должны называться рисуемыми с суффиксом для языка и языка и региональных параметров. Например, папка для испанского языка называется drawable-es. Имя папки должно содержать изображения для языка и языка и региональных параметров по умолчанию. Действие сборки каждого образа должно иметь значение AndroidResource.
Примечание.
Вместо установки отдельных файлов в действие сборки AndroidResource содержимое определенной папки можно задать для этого действия сборки, добавив следующий XML-файл в файл проекта приложения (CSPROJ):
<ItemGroup Condition="$(TargetFramework.Contains('-android'))">
<AndroidResource Include="Platforms\Android\Resources\**" TargetPath="%(RecursiveDir)%(Filename)%(Extension)" />
</ItemGroup>
Этот пример задает любое содержимое в папке Platform\Android\Resources , включая содержимое в вложенных папках, действие сборки AndroidResource . Он также задает выходной путь для каждого файла с этим действием сборки.
При указании языка верхнего уровня, например es, требуются только два символа в имени папки. Однако при указании полного языкового стандарта для формата имени папки требуется дефис и строчная буква r, чтобы отделить язык от языка и региональных параметров. Например, папка для мексиканского языкового стандарта (es-MX) должна называться drawable-es-rMX. Имена файлов изображений в папке каждого языкового стандарта должны быть одинаковыми:
iOS
В iOS локализованные изображения хранятся с помощью соглашения об именовании на основе папок в папке Platform\iOS\Resources . Папки должны быть названы языком и необязательным языком и языком и региональными параметрами, а затем lproj. Например, папка для испанского языка называется es.lproj. Действие сборки каждого образа должно иметь значение BundleResource.
Примечание.
Вместо установки отдельных файлов в действие сборки BundleResource содержимое определенной папки можно задать для этого действия сборки, добавив следующий XML-код в файл проекта приложения (CSPROJ):
<ItemGroup Condition="$(TargetFramework.Contains('-ios'))">
<BundleResource Include="Platforms\iOS\Resources\**" TargetPath="%(RecursiveDir)%(Filename)%(Extension)" />
</ItemGroup>
В этом примере в папке Platform\iOS\Resources , включая содержимое в вложенных папках, устанавливается действие сборки BundleResource . Он также задает выходной путь для каждого файла с этим действием сборки.
При указании языка верхнего уровня, например es, требуются только два символа в имени папки. Однако при указании полного языкового стандарта формат имени папки требует дефиса для разделения языка и региональных параметров. Например, папка для мексиканского языкового стандарта (es-MX) должна называться es-MX.lproj. Имена файлов изображений в папке каждого языкового стандарта должны быть одинаковыми:
Кроме того, в файле проекта необходимо задать IPhoneResourcePrefix
для свойства сборки папку, содержащую локализованные папки образа:
<PropertyGroup Condition="$(TargetFramework.Contains('-ios'))">
<IPhoneResourcePrefix>Platforms/iOS/Resources</IPhoneResourcePrefix>
</PropertyGroup>
Если изображение отсутствует для определенного языка, iOS возвращается в папку языка по умолчанию и загружает изображение из нее.
Mac Catalyst
В Mac Catalyst локализованные образы хранятся с помощью соглашения об именовании на основе папок в папке Platform\MacCatalyst\Resources . Папки должны быть названы языком и необязательным языком и языком и региональными параметрами, а затем lproj. Например, папка для испанского языка называется es.lproj. Действие сборки каждого образа должно иметь значение BundleResource.
Примечание.
Вместо установки отдельных файлов в действие сборки BundleResource содержимое определенной папки можно задать для этого действия сборки, добавив следующий XML-код в файл проекта приложения (CSPROJ):
<ItemGroup Condition="$(TargetFramework.Contains('-maccatalyst'))">
<BundleResource Include="Platforms\MacCatalyst\Resources\**" TargetPath="%(RecursiveDir)%(Filename)%(Extension)" />
</ItemGroup>
Этот пример задает любое содержимое в папке Platform\MacCatalyst\Resources , включая содержимое в вложенных папках, в действие сборки BundleResource . Он также задает выходной путь для каждого файла с этим действием сборки.
При указании языка верхнего уровня, например es, требуются только два символа в имени папки. Однако при указании полного языкового стандарта формат имени папки требует дефиса для разделения языка и региональных параметров. Например, папка для мексиканского языкового стандарта (es-MX) должна называться es-MX.lproj. Имена файлов изображений в папке каждого языкового стандарта должны быть одинаковыми:
Кроме того, в файле проекта необходимо задать IPhoneResourcePrefix
для свойства сборки папку, содержащую локализованные папки образа:
<PropertyGroup Condition="$(TargetFramework.Contains('-maccatalyst'))">
<IPhoneResourcePrefix>Platforms/MacCatalyst/Resources</IPhoneResourcePrefix>
</PropertyGroup>
Если изображение отсутствует для определенного языка, Mac Catalyst возвращается в папку языка по умолчанию и загружает изображение из нее.
Windows
В Windows локализованные образы хранятся с помощью соглашения об именовании на основе папок в папке Platform\Windows\Assets\Images . Папки должны называться языком и необязательным языком и языком и региональными параметрами. Например, папка для испанского языка называется es, а для мексиканского языкового стандарта — es-MX. Действие сборки каждого изображения должно иметь значение Content.
Примечание.
Вместо установки отдельных файлов в действие сборки содержимого содержимое определенной папки можно задать для этого действия сборки, добавив следующий XML-файл в файл проекта приложения (CSPROJ):
<ItemGroup Condition="$(TargetFramework.Contains('-windows'))">
<Content Include="Platforms\Windows\Assets\Images\**" TargetPath="%(RecursiveDir)%(Filename)%(Extension)" />
</ItemGroup>
Этот пример задает любое содержимое в папке Platform\Windows\Assets\Images, включая содержимое в вложенных папках, в действие сборки содержимого. Он также задает выходной путь для каждого файла с этим действием сборки.
При указании языка верхнего уровня, например es, требуются только два символа в имени папки. Однако при указании полного языкового стандарта формат имени папки требует дефиса для разделения языка и региональных параметров. Например, папка языкового стандарта Мексики (es-MX) должна называться es-MX. Имена файлов изображений в папке каждого языкового стандарта должны быть одинаковыми:
Использование локализованных изображений
В Android, iOS, Mac Catalyst и Windows локализованные образы можно использовать, задав Source свойство Image файла образа:
<Image Source="flag.png" />
Однако для работы с Windows необходимо изменить файл проекта приложения, если вы добавили <Content />
элемент MSBuild для каждого локализованного образа. Это можно сделать, изменив CSPROJ-файл, чтобы удалить <Content />
элемент MSBuild для каждого образа. Затем добавьте следующий элемент MSBuild:
<ItemGroup Condition="$(TargetFramework.Contains('-windows'))">
<Content Include="Platforms\Windows\Assets\Images\**" TargetPath="%(RecursiveDir)%(Filename)%(Extension)" />
</ItemGroup>
Это гарантирует, что все изображения в вложенных папках платформ\Windows\Assets\Images копируются в корневой каталог пакета приложения.
Локализация имени приложения
Для локализации имени приложения требуется функциональность платформы.
Android
В Android локализованное имя приложения можно хранить с помощью соглашения об именовании на основе папок в папке Platform\Android\Resources . Папки должны называться значениями с суффиксом для языка и языка и языка и региональных параметров. Например, папка испанского языка называется значениями es. Добавьте файл Strings.xml с действием сборки AndroidResource в каждую папку, которая задает строку локализованным именем приложения.
Примечание.
Вместо установки отдельных файлов в действие сборки AndroidResource содержимое определенной папки можно задать для этого действия сборки, добавив следующий XML-файл в файл проекта приложения (CSPROJ):
<ItemGroup Condition="$(TargetFramework.Contains('-android'))">
<AndroidResource Include="Platforms\Android\Resources\**" TargetPath="%(RecursiveDir)%(Filename)%(Extension)" />
</ItemGroup>
Этот пример задает любое содержимое в папке Platform\Android\Resources , включая содержимое в вложенных папках, действие сборки AndroidResource . Он также задает выходной путь для каждого файла с этим действием сборки.
При указании языка верхнего уровня, например es, требуются только два символа в имени папки. Однако при указании полного языкового стандарта для формата имени папки требуется дефис и строчная буква r, чтобы отделить язык от языка и региональных параметров. Например, папка языкового стандарта Мексики (es-MX) должна быть названа значениями-es-rMX.
Каждая переведенная строка — это XML-элемент с идентификатором ресурса, указанным в качестве name
атрибута, и преобразованной строкой в качестве значения. Вам нужно экранировать строку в соответствии с обычными правилами XML, и name
он должен быть допустимым идентификатором ресурса Android (без пробелов или дефисов).
Таким образом, чтобы локализовать имя приложения, создайте файл Strings.xml и добавьте <string>
элемент в качестве дочернего <resources>
элемента. Затем задайте для его name
атрибута подходящий идентификатор с преобразованной строкой в качестве значения:
<resources>
<!-- French -->
<string name="app_name">Maison</string>
</resources>
Затем, чтобы использовать локализованное имя приложения в приложении, добавьте Label
свойство Activity
в класс приложения MainActivity
и задайте для нее значение @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 локализованное имя приложения сохраняется с помощью соглашения об именовании на основе папок в папке Platform\iOS\Resources . Папки должны быть названы языком и необязательным языком и языком и региональными параметрами, а затем lproj. Например, папка для испанского языка называется es.lproj. Добавьте файл InfoPlist.strings с действием сборки BundleResource в каждую CFBundleDisplayName
папку, которая задает ключ и значение.
Примечание.
Вместо установки отдельных файлов в действие сборки BundleResource содержимое определенной папки можно задать для этого действия сборки, добавив следующий XML-код в файл проекта приложения (CSPROJ):
<ItemGroup Condition="$(TargetFramework.Contains('-ios'))">
<BundleResource Include="Platforms\iOS\Resources\**" TargetPath="%(RecursiveDir)%(Filename)%(Extension)" />
</ItemGroup>
В этом примере в папке Platform\iOS\Resources , включая содержимое в вложенных папках, устанавливается действие сборки BundleResource . Он также задает выходной путь для каждого файла с этим действием сборки.
Синтаксис локализованных строковых значений:
/* comment */
"key"="localized-value";
Следует экранировать следующие символы в строках:
- Цитата клиента (
\"
) \\
Обратной косой черты\n
Newline
Таким образом, чтобы локализовать имя приложения, создайте файл InfoPlist.strings и добавьте значение ключа в CFBundleDisplayName
файл:
/* French */
CFBundleDisplayName="Maisons";
Другие ключи, которые можно использовать для локализации строк для конкретного приложения:
CFBundleName
— задает короткое имя пакета приложений, которое может отображаться пользователям в таких ситуациях, как отсутствие значения.CFBundleDisplayName
CFBundleShortVersionString
— указывает номер версии выпуска пакета приложений.NSHumanReadableCopyright
— уведомление об авторских правах для пакета приложений.
Кроме того, в файле проекта необходимо задать для свойства сборки папку IPhoneResourcePrefix
, содержащую локализованные папки:
<PropertyGroup Condition="$(TargetFramework.Contains('-ios'))">
<IPhoneResourcePrefix>Platforms/iOS/Resources</IPhoneResourcePrefix>
</PropertyGroup>
Mac Catalyst
В Mac Catalyst локализованное имя приложения сохраняется с помощью соглашения об именовании на основе папок в папке Platform\MacCatalyst\Resources . Папки должны быть названы языком и необязательным языком и языком и региональными параметрами, а затем lproj. Например, папка для испанского языка называется es.lproj. Добавьте файл InfoPlist.strings с действием сборки BundleResource в каждую CFBundleDisplayName
папку, которая задает ключ и значение.
Примечание.
Вместо установки отдельных файлов в действие сборки BundleResource содержимое определенной папки можно задать для этого действия сборки, добавив следующий XML-код в файл проекта приложения (CSPROJ):
<ItemGroup Condition="$(TargetFramework.Contains('-maccatalyst'))">
<BundleResource Include="Platforms\MacCatalyst\Resources\**" TargetPath="%(RecursiveDir)%(Filename)%(Extension)" />
</ItemGroup>
Этот пример задает любое содержимое в папке Platform\MacCatalyst\Resources , включая содержимое в вложенных папках, в действие сборки BundleResource . Он также задает выходной путь для каждого файла с этим действием сборки.
Синтаксис локализованных строковых значений:
/* comment */
"key"="localized-value";
Следует экранировать следующие символы в строках:
- Цитата клиента (
\"
) \\
Обратной косой черты\n
Newline
Таким образом, чтобы локализовать имя приложения, создайте файл InfoPlist.strings и добавьте значение ключа в CFBundleDisplayName
файл:
/* French */
CFBundleDisplayName="Maisons";
Другие ключи, которые можно использовать для локализации строк для конкретного приложения:
CFBundleName
— определяет короткое имя пакета приложений, которое может отображаться пользователям в таких ситуациях, как отсутствие значения.CFBundleDisplayName
CFBundleShortVersionString
— указывает номер версии выпуска пакета приложений.NSHumanReadableCopyright
— уведомление об авторских правах для пакета приложений.
Кроме того, в файле проекта необходимо задать для свойства сборки папку IPhoneResourcePrefix
, содержащую локализованные папки:
<PropertyGroup Condition="$(TargetFramework.Contains('-maccatalyst'))">
<IPhoneResourcePrefix>Platforms/MacCatalyst/Resources</IPhoneResourcePrefix>
</PropertyGroup>
Windows
В Windows имя приложения определяется в манифесте пакета приложения. Для локализации имени приложения необходимо сначала указать язык по умолчанию для приложения, а затем создать строковый файл ресурсов для каждого языкового стандарта, который вы планируете поддерживать. Строковый ресурс, представляющий локализованное имя приложения, можно использовать в манифесте пакета приложения с помощью ms-resource
схемы URI.
Дополнительные сведения о локализации строк в манифесте пакета приложения см. в разделе "Локализация строк" в манифесте пользовательского интерфейса и пакета приложения.
Указание языка по умолчанию
Чтобы локализовать имя приложения, приложение Windows должно сначала задать язык по умолчанию. Это язык, ресурсы которого используются, если локализованные ресурсы для определенного языка не найдены. Чтобы указать язык по умолчанию, выполните указанные ниже действия.
В Обозреватель решений откройте файл Packageappxmanifest в редакторе манифеста пакета.
В редакторе манифеста пакета на вкладке "Приложение " задайте для поля языка по умолчанию выбранный язык по умолчанию:
Сохранение изменений.
Как минимум, необходимо указать строковый ресурс для имени приложения для языка по умолчанию. Это ресурс, загруженный, если лучшего соответствия не удается найти для предпочитаемого языка пользователя или параметров языка отображения.
Создание файлов ресурсов Windows
В Windows локализованное имя приложения должно храниться в файле ресурсов Windows для каждого языкового стандарта. Файл ресурсов Windows — это XML-файл с расширением RESW , скомпилированным в двоичном формате и хранящимся в PRI-файле . Resw-файл для каждого языкового стандарта должен называться Resources.resw и храниться с помощью соглашения об именовании на основе папок в папке Platform\Windows\Strings. Папки должны называться языком и необязательным языком и языком и региональными параметрами. Например, папка для испанского языка называется es, а для мексиканского языкового стандарта — es-MX.
В настоящее время нет шаблона элемента Visual Studio для создания файла ресурсов Windows в приложении .NET MAUI. Таким образом, чтобы создать файл ресурсов Windows для каждого языкового стандарта:
В папке Platform\Windows проекта приложения .NET MAUI создайте папку Strings .
В папке Strings создайте папку для каждого языкового стандарта.
В папке для каждого языкового стандарта создайте файл с именем Resources.resw , содержащий следующий XML- код:
<?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>
Примечание.
Файлы ресурсов Windows используют действие сборки
PRIResource
. Это действие сборки не требует настройки для каждого RESW-файла в приложении .NET MAUI, так как оно неявно применяется.Откройте каждый файл Resources.resw и добавьте строковый ресурс, представляющий имя приложения:
Примечание.
Идентификаторы ресурсов являются нечувствительными к регистру и должны быть уникальными для каждого файла ресурсов.
Сохраните каждый файл ресурсов Windows.
Пример требуемой папки и структуры файлов показан на следующем снимке экрана:
Использование локализованного имени приложения
Строковый ресурс, представляющий локализованное имя приложения, можно использовать с помощью ms-resource
схемы URI:
В Обозреватель решений откройте файл Packageappxmanifest в редакторе манифеста пакета.
В редакторе манифеста пакета на вкладке "Приложение" задайте поле
ms-resource:
отображаемого имени, за которым следует имя строкового ресурса, идентифицирующее имя приложения:Сохранение изменений.
Важно!
Если resw-файлы хранятся в другой сборке проекта приложения .NET MAUI, необходимо указать полный путь к имени ресурса. Для этого используется формат ms-resource:Assembly/ResourceFilename/Resource
.
Локализация справа налево
Направление потока или направление макета — это направление, в котором элементы пользовательского интерфейса на странице сканируются глазом. Некоторые языки, такие как арабский и иврит, требуют, чтобы элементы пользовательского интерфейса располагались в направлении справа налево. Приложения .NET MAUI автоматически учитывают направление потока устройства на основе выбранного языка и региона. Сведения о том, как получить направление потока устройства на основе его языкового стандарта, см. в разделе "Получение направления макета".
Чтобы переопределить направление потока приложения, задайте Window.FlowDirection свойство. Кроме того, задайте VisualElement.FlowDirection свойство на основе каждого элемента. Эти свойства получают или задают направление, в котором элементы пользовательского интерфейса выполняются в любом родительском элементе, который управляет их макетом и должен иметь одно из FlowDirection значений перечисления:
LeftToRight
RightToLeft
MatchParent
FlowDirection Задание свойства RightToLeft
для элемента задает выравнивание справа, порядок чтения справа налево и макет элемента управления, который будет передаваться справа налево.
Предупреждение
FlowDirection Изменение свойства во время выполнения приводит к дорогостоящим процессам макета, влияющим на производительность.
Значение свойства по умолчанию FlowDirection для элемента MatchParent
. Таким образом, элемент наследует значение свойства FlowDirection
от своего родительского элемента в визуальном дереве, и любой элемент может переопределить значение, которое он получает от своего родительского объекта.
Совет
Если необходимо изменить направление потока, задайте FlowDirection свойство в окне, странице или корневом макете. Это приводит ко всем элементам, содержащимся в приложении, странице или корневом макете, соответствующим образом реагировать на направление потока.
Настройка платформы
Для включения языковых стандартов с направлением потока справа налево требуется настройка конкретной платформы.
Android
Приложения, созданные с помощью шаблона проекта приложения .NET MAUI, автоматически включают поддержку языковых стандартов справа налево. Эта поддержка включена атрибутом, заданным android:supportsRtl
true
на <application>
узле в файле AndroidManifest.xml приложения:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application ... android:supportsRtl="true" />
...
</manifest>
Затем можно протестировать локализацию справа налево, изменив устройство или эмулятор для использования языка справа налево. Кроме того, если вы активировали параметры разработчика в приложении Параметры, можно включить направление макета Force RTL в Параметры > "Параметры разработчика". Сведения о настройке параметров разработчика см. в разделе "Настройка параметров разработчика на устройстве" на developer.android.com.
IOS и Mac Catalyst
Требуемый языковой стандарт с направлением потока справа налево необходимо добавить в качестве поддерживаемого языка в элементы массива для ключа CFBundleLocalizations
в файле Info.plist. В следующем примере показано добавление арабского языка в массив для ключа CFBundleLocalizations
:
<key>CFBundleLocalizations</key>
<array>
<string>en</string>
<string>ar</string>
</array>
Затем можно протестировать локализацию справа налево, изменив язык и регион на устройстве или симулятор на языковой стандарт справа налево, указанный в Info.plist.
Windows
Необходимые языковые ресурсы следует указать в узле <Resources>
файла Package.appxmanifest. <Resource />
Замените <Resource Language="x-generate">
элементами для каждого поддерживаемого языка. Например, следующая разметка указывает, что доступны локализованные ресурсы en и ar:
<Resources>
<Resource Language="en" />
<Resource Language="ar" />
</Resources>
После этого локализацию справа налево протестировать, изменив язык и регион на устройстве на соответствующий языковой стандарт с направлением потока справа налево.
Тестирование локализации
Во время выполнения приложение загружает соответствующие локализованные ресурсы на основе потока на основе языка и региональных параметров, заданных свойством CurrentUICulture .
Тестирование локализации лучше всего достигается путем изменения языка устройства в приложении Параметры на каждом устройстве.
Предупреждение
Хотя можно задать значение CurrentUICulture в коде, результирующее поведение несогласовано на разных платформах, поэтому это не рекомендуется для тестирования.