В прошлых темах мы рассмотрели локализацию в коде C#, но гораздо проще было бы локализовать элементы интерфейса сразу же в xaml. Для этого возьмем проект из прошлой темы.
Чтобы добавить в приложение возможность локализации элементов xaml, надо добавить класс расширения разметки. Итак, добавим в главный проект следующий класс:
using System; using Xamarin.Forms; using Xamarin.Forms.Xaml; using System.Resources; using System.Globalization; using System.Reflection; namespace HelloApp { [ContentProperty("Text")] public class TranslateExtension : IMarkupExtension { readonly CultureInfo ci; const string ResourceId = "HelloApp.Resource"; public TranslateExtension() { ci = DependencyService.Get<ILocalize>().GetCurrentCultureInfo(); } public string Text { get; set; } public object ProvideValue(IServiceProvider serviceProvider) { if (Text == null) return ""; ResourceManager resmgr = new ResourceManager(ResourceId, typeof(TranslateExtension).GetTypeInfo().Assembly); var translation = resmgr.GetString(Text, ci); if (translation == null) { translation = Text; } return translation; } } }
В строке const string ResourceId = "HelloApp.Resource";
устанавливаются ресурсы для локализации. Так как у меня пространство имен проекта
называется HelloApp
, а файл ресурсов по умолчанию размещен в корне проекта и называется Resource.resx
,
то полное имя ресурса будет HelloApp.Resource
.
Для извлечения ресурсов используется класс ResourceManager
и его метод GetString()
Теперь применим данный класс в xaml:
<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="HelloApp.MainPage" xmlns:local="clr-namespace:HelloApp;assembly=HelloApp"> <StackLayout> <Label x:Name="myLabel" FontSize="Large" Text="{local:Translate Header}" /> <Entry x:Name="myEntry" Placeholder="{local:Translate LoginText}" /> <Button x:Name="myButton" FontSize="Large" Text="{local:Translate SaveButton}" /> </StackLayout> </ContentPage>
Чтобы получить доступ к классу, надо подключить текущее пространство имен проекта: xmlns:local="clr-namespace:HelloApp;assembly=HelloApp"
Затем мы можем использовать привязку у тех свойствам элементов, которые надо локализовать: Text="{local:Translate Header}"
. В данном случае
local ссылается на текущее пространство имен, "Translate" ссылается на класс TranslateExtension
- по умолчанию суффикс Extension отбрасывается.
И затем указывается называется имя ресурса, к которому идет привязка.
В итоге мы можем убрать локализацию из класса приложения App, которая была определена в прошлых темеах, теперь он будет просто создавать стартовую страницу:
public partial class App : Application { public App() { InitializeComponent(); MainPage = new MainPage(); } }