2009-05-02 2 views
19

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

ответ

17

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

  • находится в стабильном состоянии реального
  • поддерживает связывание подобный стиль письма, как Text = {LocText ResAssembly:ResFile:ResKey}
  • работ с .resx-резервный механизм (например, ан-нас -> ан -> независимая культура)
  • поддерживает форсирование культуры (например,«Это должно быть английским все время»)
  • работы с нормальными свойствами зависимостей
  • работы с шаблонами управления
  • может быть использован в XAML (действительно: P) без каких-либо дополнительных пространств имен
  • может быть использована в код для привязки локализованных значений к динамически сгенерированным элементам управления
  • инвентарь INotifyPropertyChanged для расширенного использования
  • поддерживает форматирование строк, например "this is the '{0}' value"
  • поддерживает префикс и суффикс значения (в настоящее время с LocText расширением)
  • находится в использовании в производственных системах (например, мое отношение продукт общественного)
  • переключение языка на время выполнения влияет НЕТ квант времени
  • может быть используется с любым файлом ресурсов (.resx) для всех сборок (также динамически загружен один во время выполнения)
  • не требует никакого процесса инициализации (например, «call 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 (может быть легко изменена)
+6

нет документации или учебника о том, как это использовать? –

+1

теперь доступна документация http://wpflocalizeextension.codeplex.com/documentation – SeriousM

32

Выполните следующие действия:

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); 

} 
+0

Любите свое предложение. Что добавить: я думаю, что мы можем сделать приложение доступным для переключения во время выполнения с помощью '{StaticResource resKey}' –

+4

Собственно, просто укажите {DynamicResource resKey}, где бы вы ни использовали ресурсы, а затем во время выполнения вызовите SelectCulture (культура) метод выше, и он будет динамически обновлять все ваши строки в новой культуре. Вместо: string str = FindResource («All_Vehicles»). ToString(); Использование: Application.Current.Resources ["All_Vehicles"] как строка – Curtis

+0

Есть ли способ изменить его во время выполнения? – albatross

1

Джош Смит написал учебник углубленную о его предпочтительном способе для этого: Creating an Internationalized Wizard in WPF.

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

0

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

Смежные вопросы