В Xamarin.Формы: как использовать локализацию независимо от языка устройства

Я разрабатываю Xamarin.Приложение Forms (проект переносной библиотеки классов) с Visual Studio 2013 CE. Сначала я фокусирую версию iOS.

Теперь я думаю о том, как сделать приложение многоязычным. Я только что прочитал официальную документацию Xamarin об этом, но я понял, что это решение принимает только системный язык целевого устройства.

в портативной библиотеке классов у меня есть папка ресурсов с тремя языками: немецкий (по умолчанию), английский и Французский.

Resource.resx
Resource.en-US.resx
Resource.fr-FR.resx
Resource.Designer.cs

Теперь я только что создал статический класс настроек, который выглядит так:

public static class Settings
{
    public static Dictionary<String, CultureInfo> Languages = new Dictionary<String, CultureInfo> { { "German", new CultureInfo("de-DE") }, { "English", new CultureInfo("en-US") }, { "French", new CultureInfo("fr-FR") } };

    public static CultureInfo CurrentCulture = Languages["German"];
    public static CultureInfo CurrentUiCulture = Languages["German"];

    public static void ChangeCurrentCultureInfo(CultureInfo cultureInfo)
    {
        Resource.Culture = cultureInfo;
    }
}

Теперь мой вопрос в том, можно ли изменить культуру в приложении во время выполнения нажатием кнопки. Может быть, что-то вроде

Settings.CurrentCulture = Settings.Languages["English"];
Settings.ChangeCurrentCultureInfo(Settings.CurrentCulture);

кто-нибудь может сказать мне, как это можно сделать?

в отношении

3 ответов


Я не верю, что вы можете сделать это из своего общего проекта PCL. Однако вы можете установить UICulture из ваших проектов, специфичных для платформы. Сделать это из полезное location (т. е. ваше приложение Forms), мы должны представить это как службу из ваших проектов платформы как зависимость.

во-первых, определите интерфейс, который описывает службу "управление культурой"."Это должно жить в сборке, на которую ссылаются ваши проекты для конкретной платформы (the общий проект PCL будет делать):

public interface ICultureInfo
{
    System.Globalization.CultureInfo CurrentCulture { get; set; }
    System.Globalization.CultureInfo CurrentUICulture { get; set; }
}

и в каждом из ваших проектов платформы включите тип, который реализует этот интерфейс:

using System;
using Xamarin.Forms;
using System.Threading;

[assembly:Dependency(typeof(YourNamespaceHere.PlatformCultureInfo))]
namespace YourNamespaceHere
{
    public class PlatformCultureInfo : ICultureInfo
    {
        #region ICultureInfo implementation

        public System.Globalization.CultureInfo CurrentCulture {
            get {
                return Thread.CurrentThread.CurrentCulture;
            }
            set {
                Thread.CurrentThread.CurrentCulture = value;
            }
        }

        public System.Globalization.CultureInfo CurrentUICulture {
            get {
                return Thread.CurrentThread.CurrentUICulture;
            }
            set {
                Thread.CurrentThread.CurrentUICulture = value;
            }
        }

        #endregion
    }
}

затем в приложении forms вы запрашиваете экземпляр реализации Платформы из Xamarin Forms DependencyService. (Примечание: любые вызовы DependencyService должны произойти после вызова форм.Init ())

как только вы его получите, вы можете установить текущую культуру пользовательского интерфейса:

var cultureInfo = Xamarin.Forms.DependencyService.Get<ICultureInfo>();
cultureInfo.CurrentUICulture = new System.Globalization.CultureInfo("fr-FR");

и вуаля, любой изменения в культуре пользовательского интерфейса будут отражены при любом последующем поиске ресурсов. Обратите внимание на использование слова "последующие" - любые формы, использующие поиск ресурсов (например, если вы используете мои удобные расширения разметки XAML локализации) не будет отражать изменение культуры, пока они не будут обновлены / перезагружены.

В заключение команда Xamarin проделала отличную работу по дублированию исходной инфраструктуры поиска ресурсов! Ему просто нужно немного подтолкнуть, чтобы получить его в мир Xamarin Формы.


наконец, я получил ответ поддержки Xamarin. Решение, о котором я думал, работает. В PCL у меня просто есть static Settings class который хранит различные CultureInfo объекты. Кроме того, я определил метод изменения текущей культуры и языка файла ресурсов.

public static void ChangeCurrentCultureInfo(CultureInfo cultureInfo)
{
    CurrentCulture = cultureInfo;
    Resource.Culture = CurrentCulture;
}

важно установить язык по умолчанию в App() конструктор перед инициализацией главной страницы. Теперь я получил listview со всеми поддерживаемыми языками с одним событием, которое вызывает ChangeCurrentCultureInfo метод.

тем не менее я хочу поблагодарить Энди Хоппер за предоставление своего решения!

в отношении


вы можете вызвать метод setLocale, доступный в каждом проекте платформы из PCL, используя интерфейс ILocalize следующим образом:

CultureInfo ci=new CultureInfo("ar");
Xamarin.Forms.DependencyService.Get<ILocalize>().SetLocale(ci);                      

AppResources.Culture = ci;