2013-12-13 4 views
6

Я пытаюсь использовать локализацию .NET в переносимой библиотеке классов для проекта Xamarin iOS/Android. Я следовал инструкциям на:Xamarin iOS localization using .NET

How to use localization in C#

И есть код, который выглядит следующим образом:

string sText = strings.enter_movie_name; 
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("fr"); 
sText = strings.enter_movie_name; 
lblEnterMovieName.Text = sText; 

Я также попытался:

ResourceManager resman = new ResourceManager(typeof(MyApplication.strings)); 
string sText = resman.GetString("enter_movie_name", new CultureInfo("fr")); 

Я создал строки .resx с enter_movie_name равным «Enter movie name:» и strings.fr.resx, равным «Entre la movie name:»

Однако sText всегда заканчивается как «Enter movie name:». Кажется, я не могу получить версию «Entre la movie name:».

Я также видел сообщение в Cross-platform Localization, но не смог его обработать. Я также не хочу использовать конкретную версию iOS в Localization on Xamarin.iOS, так как я хотел бы иметь возможность получать мои строки из независимой от платформы библиотеки.

Может ли кто-нибудь указать, где я ошибаюсь?

+2

На самом деле я просто разместил аналогичный вопрос здесь: http://stackoverflow.com/questions/20608106/how-do-i-get-resx-files-to-work-with-xamarin-ios-for-localization Кажется, что специфичные для языка файлы resx (strings.fr.resx) «скомпилированы» в файл fr \ MyApplication.resources.dll, который не входит в приложение. Поэтому он всегда выбирает значение по умолчанию. – BoKDamgaard

ответ

7

Я создал немного уродливое решение, но оно работает. Что я сделал это сделал папку под названием 'струны' в моем Portable Class Library (PCL), так и внутри, что создаваемые файлы называются:

  • strings.resx
  • strings_fr.resx
  • strings_ja_JP.resx

Я установил все из них как встроенный ресурс с помощью специального инструмента как ResXFileCodeGenerator. Это означает, что у меня есть отдельная DLL ресурсов для каждого языка.

В прошивкой можно затем получить локаль по телефону:

string sLocale = NSLocale.CurrentLocale.LocaleIdentifier; 

Я предполагаю, что есть андроида эквивалент с помощью Locale, но я не знаю, что это такое.

Это дает мне строку типа «ja_JP» или «fr_FR» или «en_GB» (обратите внимание, что это символы подчеркивания, а не тире). Затем я использую это со следующим статическим классом, который я создал, чтобы получить соответствующий менеджер ресурсов и получить из него строку.

Если задана локаль aa_BB, она сначала ищет strings_aa_BB, затем для strings_aa, затем для строк.

public static class Localise 
{ 
    private const string STRINGS_ROOT = "MyPCL.strings.strings"; 

    public static string GetString(string sID, string sLocale) 
    { 
     string sResource = STRINGS_ROOT + "_" + sLocale; 
     Type type = Type.GetType(sResource); 
     if (type == null) 
     { 
      if (sLocale.Length > 2) { 
       sResource = STRINGS_ROOT + "_" + sLocale.Substring(0, 2); // Use first two letters of region code 
       type = Type.GetType(sResource); 
      } 
     } 
     if (type == null) { 
      sResource = STRINGS_ROOT; 
      type = Type.GetType(sResource); 
      if (type == null) 
      { 
       System.Diagnostics.Debug.WriteLine("No strings resource file when looking for " + sID + " in " + sLocale); 
       return null; // This shouldn't ever happen in theory 
      } 
     } 
     ResourceManager resman = new ResourceManager(type); 
     return resman.GetString(sID); 
    } 
} 

Пример того, как это будет использоваться (со ссылкой на приведенный выше код) будет:

string sText = Localise.GetString("enter_movie_name", sLocale); 
lblEnterMovieName.Text = sText; 

Существенным недостатком этого является то, что все виды должны иметь их текст установлен программно, но имеет потенциал роста, что переводы могут выполняться один раз, а затем повторно использоваться на многих платформах. Они также остаются отдельно от основного кода в своих собственных DLL и поэтому могут быть перекомпилированы индивидуально, если это необходимо.

3

Я создал аналогичное решение для принятого ответа, но используя txt-файлы вместо Resx и nuget готов к работе: https://github.com/xleon/I18N-Portable. Сообщение в блоге here.

Другие улучшения:

  • "anyKey".Translate(); // from anywhere
  • Автоматическое определение текущей культуры
  • Получить список поддерживаемых переводов: List<PortableLanguage> languages = I18N.Current.Languages;
  • поддержка связывания данных в MVVM рамочные/Xamarin.Forms
  • и т.д.