вторник, 14 июня 2011 г.

Локализация строк в WPF приложениях

При использовании материалов ссылка на источник обязательна.
В предыдущем посте я рассказывал о том, как можно организовать локализацию приложения WPF с использованием утилиты LocBaml от Microsoft. Этот способ позволяет удобно организовать процесс локализации свойств интерфейсных элементов, объявленных в XAML. Однако оставался открытым вопрос локализации строк, которые используются непосредственно к коде, например, тексты сообщений и т.п.
Простота локализации свойств, объявленных в XAML невольно подталкивает к тому, чтобы оформить строки, которым требуется перевод, в виде объектных ресурсов:

<system:string x:Key="StringKey" x:Uid="StringUid">
   Строка для локализации
</system:string>

Но у этого простого и очевидного решения есть два больших недостатка:
  1. Объектные ресурсы идентифицируются строковыми ключами и точность их написания в коде программы не контролируется на этапе компиляции и не позволяет использовать IntelliSense
  2. При извлечении ресурсов в CSV с помощью LocBaml соответствующие строки не выделяются атрибутами локализации, что затрудняет выделение необходимых для перевода строк в полном CSV файле
Поэтому простое решение пришлось немного усложнить. Суть усложнений сводится к двум пещам:
  1. Использовать вместо класса System.String другого класса, имеющего строковое свойство, чтобы указать для него атрибуты локализации.
  2. Использовать генерацию кода для доступа к строкам, представленным в XAML.
На практике это выглядит следующим образом.
Для хранения строк в виде объектных ресурсов заводится класс:

public class StringObject 
{
public StringObject(string val){
Value = val;
}
public StringObject() { }

public string Value {get; set;}

public override string ToString(){
return Value;
}
}





Далее, заводится словарь ресурсов, например strings.xaml, в котором объявляются строки, которые необходимо переводить:


<StringObject  x:Uid="StatusChanged" x:Key="StatusChanged"
Localization.Attributes="Value (Readable Modifiable Text)"

Value="Status is changed" />


Объявления строк сопровождаются атрибутами локализации, необходимыми для выделения в CSV строк, предназначенных для локализации. Ссылка на словарь ресурсов включается в app.xaml. Для упрощения доступа к строкам из кода в класс приложения добавляется метод:

public static string RString(string name)
{
    try
    {
        return Application.Current.Resources[name].ToString();
    }
    catch (System.Exception)
    {
        return "load string " + name + " failed";
    }
}
 И, в заключение, в Pre-build event проекта добавляется строка
StringTableBuilder.exe "$(ProjectDir)strings.xaml"

где StringTableBuilder.exe - утилита генерации исходного кода по словарю ресурсов (см. исходник). Эта утилита генерирует файл strings.cs, в котором объявляется класс StringTable, содержащий статические свойства, для обращения к строкам в ресурсах, например:


public const string StatusChangedKey = "StatusChanged";
 

public static string StatusChanged
{
    get
    {
       return App.RString(StringTable.StatusChangedKey);
    }
}

Таким образом, для обращения к этой строке в коде достаточно написать StringTable.StatusChanged.
Вот и все. Теперь все строки объявлены в XAML и обрабатываются по одной технологии.

Связанные материалы:



  1. Технология локализации WPF приложений
  2. Форматирование строк при связывании данных
  3. Использование перечислений (enum) в локализуемых приложениях

1 комментарий:

  1. Если Вы заинтересованы в локализации web-ПО, ПО для персональных компьютеров, ПО для мобильных устройств либо иного вида программного обеспечения, я рекомендую Вам использовать этот инструмент на базе web: https://poeditor.com/

    ОтветитьУдалить