Мультиязычность в WPF

Можете ли вы порекомендовать хороший способ внедрения многоязычной системы для приложения WPF? Метод, который я сейчас использую, включает в себя XML, классы и расширение xaml. В большинстве случаев работает нормально, но когда мне приходится иметь дело с динамическими метками или динамическим текстом в целом, это требует дополнительных усилий. Я бы хотел, чтобы программист работал только над основной проблемой и забыл о проблемах языка.

4 ответа

Решение

Я использую расширение локализации WPF. Это действительно простой способ локализации любого типа DependencyProperty на DependencyObject s.

  • находится в реальном стабильном состоянии
  • поддерживает обязательный стиль письма Text = {LocText ResAssembly:ResFile:ResKey}
  • работает с механизмом.resx-fallback (например, en-us -> en -> независимая культура)
  • поддерживает форсирование культуры (например, "это должно быть все время на английском")
  • работает с обычными свойствами зависимостей
  • работает с шаблонами управления
  • может использоваться в XAML (действительно:P) без каких-либо дополнительных пространств имен
  • может использоваться в коде для привязки локализованных значений к динамически генерируемым элементам управления
  • инвентарь INotifyPropertyChanged для расширенного использования
  • поддерживает форматирование строки, например "this is the '{0}' value"
  • поддерживает значения префикса и суффикса (в настоящее время LocText расширение)
  • используется в продуктивных системах (например, мой продукт по связям с общественностью)
  • переключение языка во время выполнения не влияет на временной интервал
  • можно использовать с любым файлом ресурсов (.resx) во всех сборках (также динамически загружаемых во время выполнения)
  • не требует какого-либо процесса инициализации (например, "вызвать xyz для регистрации специального словаря локализации")
  • доступен во время разработки (MS Expression Blend, MS Visual Studio 2008 (Normal и SP1)
  • изменение выбранного языка возможно во время разработки
  • может локализовать любой тип данных, при условии, что конвертер (TypeConverter) поскольку оно существует (расширяется) LocalizeExtension)
  • имеет встроенную поддержку Text верхний Text ниже Text, Image s, Brush эс, Double а также Thickness
  • не влияет на утечки памяти
  • оставляет UID собственность нетронутой
  • предлагает SpecificCulture использовать как IFormatProvider (например (123.20).ToString(LocalizeDictionary.SpecificCulture) = "123.20" или же "123,20")
  • предлагает некоторую функциональность для проверки и получения значений ресурсов в коде
  • не меняет культуру на Thread.CurrentCulture или же Thread.CurrentUICulture (можно легко изменить)

Следуй этим шагам:

1) Поместить все String фрагменты в отдельном файле ресурсов.

Пример: StringResources.xaml:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:system="clr-namespace:System;assembly=mscorlib">

    <!-- String resource that can be localized -->
    <system:String x:Key="All_Vehicles">All Vehicles</system:String>

</ResourceDictionary>

2) Сделайте копии для каждого языка и добавьте их (переведенные) в объединенные словари. Не забудьте добавить ISO-код страны, чтобы все было проще.

пример App.xaml:

<Application x:Class="WpfStringTables.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="Window1.xaml">
    <Application.Resources>
        <ResourceDictionary >
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="StringResources.de-DE.xaml" />
                <ResourceDictionary Source="StringResources.nl-NL.xaml" />
                <ResourceDictionary Source="StringResources.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

Последний файл ресурсов со строками будет использоваться для замены текстовых частей в коде.

3a) Используйте текстовые части из String Таблица:

пример Window1.xaml:

<Window x:Class="WpfStringTables.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
    <Grid>
        <Button Margin="51,82,108,129" Name="AllVehiclesButton" 
                Content="{StaticResource All_Vehicles}"/>
    </Grid>
</Window>

3b) Загрузите ресурс из кода (используйте этот код, только если вы не хотите устанавливать через XAML):

void PageLoad()
{
  string str = FindResource("All_Vehicles").ToString();
}

4) Переключиться на новую культуру при запуске приложения:

Codesnippet от App.xaml.cs:

public static void SelectCulture(string culture)    
{      
    if (String.IsNullOrEmpty(culture))
        return;

    //Copy all MergedDictionarys into a auxiliar list.
    var dictionaryList = Application.Current.Resources.MergedDictionaries.ToList();

    //Search for the specified culture.     
    string requestedCulture = string.Format("StringResources.{0}.xaml", culture);
    var resourceDictionary = dictionaryList.
        FirstOrDefault(d => d.Source.OriginalString == requestedCulture);

    if (resourceDictionary == null)
    {
        //If not found, select our default language.             
        requestedCulture = "StringResources.xaml";
        resourceDictionary = dictionaryList.
            FirstOrDefault(d => d.Source.OriginalString == requestedCulture);
    }

    //If we have the requested resource, remove it from the list and place at the end.     
    //Then this language will be our string table to use.      
    if (resourceDictionary != null)
    {
        Application.Current.Resources.MergedDictionaries.Remove(resourceDictionary);
        Application.Current.Resources.MergedDictionaries.Add(resourceDictionary);
    }

    //Inform the threads of the new culture.     
    Thread.CurrentThread.CurrentCulture = new CultureInfo(culture);
    Thread.CurrentThread.CurrentUICulture = new CultureInfo(culture);

}

Используя эту статью, мне удалось легко использовать файлы ресурсов для обработки многоязычных окон WPF. http://www.codeproject.com/KB/WPF/WPF_Resx_Localization.aspx Вы должны проверить это, потому что это действительно просто и эффективно.

Джош Смит написал подробное руководство о своем предпочтительном методе для этого: создание интернационализированного мастера в WPF.

Это может указать вам на большой редизайн (это решение MVVM), но использование MVVM, похоже, того стоит и по другим причинам.

Другие вопросы по тегам