Многоязычие в WPF [закрыто]
-
03-07-2019 - |
Вопрос
Можете ли вы порекомендовать хороший способ реализации многоязычной системы для приложения WPF?Метод, который я использую прямо сейчас, включает XML, классы и расширение xaml.В большинстве случаев это работает нормально, но когда мне приходится иметь дело с динамическими метками или динамическим текстом в целом, это требует некоторых дополнительных усилий.Я бы хотел, чтобы программист работал только над основной проблемой и забыл о проблемах с языком.
Решение
Я использую Расширение локализации WPF.Это действительно простой способ локализовать любой тип DependencyProperty
вкл . DependencyObject
s.
- находится в реальном стабильном состоянии
- поддерживает стиль написания, подобный привязке, например
Text = {LocText ResAssembly:ResFile:ResKey}
- работает с резервным механизмом .resx (например,ru-сша -> ru -> независимая культура)
- поддерживает культурное форсирование (например,"это должно быть все время на английском")
- работает с обычными свойствами зависимостей
- работает с шаблонами элементов управления
- может использоваться в XAML (на самом деле: P) без каких-либо дополнительных пространств имен
- может использоваться в коде для привязки локализованных значений к динамическим генерируемым элементам управления
- орудия труда
INotifyPropertyChanged
для расширенного использования - поддерживает форматирование строк, например
"this is the '{0}' value"
- поддерживает значения префиксов и суффиксов (в настоящее время с
LocText
расширение) - используется в производственных системах (например, в моем продукте по связям с общественностью).
- переключение языка на время выполнения влияет НЕТ временная щель
- может использоваться с любым файлом ресурсов (
.resx
) во всех сборках (также динамически загружаемых во время выполнения) - не нуждается в каком-либо процессе инициализации (например, "вызовите xyz, чтобы зарегистрировать специальный словарь локализации").
- доступно во время разработки (MS Expression Blend, MS Visual Studio 2008 (обычный и с пакетом обновления 1)).
- изменение выбранного языка возможно во время разработки
- может локализовать любой тип данных, при условии, что конвертер (
TypeConverter
) ибо оно существует (распространяетсяLocalizeExtension
) - имеет встроенную поддержку для
Text
, верхнийText
, нижнийText
,Image
s,Brush
es,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 .
Это может указать вам на большой редизайн (это решение MVVM ), но использование MVVM кажется оправданным и по другим причинам.
Используя эту статью, мне удалось легко использовать файлы ресурсов для обработки многоязычных окон WPF. http://www.codeproject.com/KB/WPF/WPF_Resx_Localization.aspx Вы должны проверить это, потому что это действительно просто и эффективно.