Многоязычный в [закрытом] WPF

Если ваш экземпляр sqlite был скомпилирован с включенным расширением JSON1 , это легко:

SELECT * FROM yourtable AS t
WHERE EXISTS (SELECT j.id FROM json_each(t.i18n) AS j
              WHERE json_extract(j.value, '$.name') LIKE 'NAME_IN%');

Однако, небольшое изменение вашей второй идеи, вытаскивая все эти JSON -объекты в строках таблицы (вместо одного столбца на язык, который быстро становится громоздким по мере роста количества языков), вероятно, является лучшим вариантом:

CREATE TABLE translations(original TEXT, language TEXT, translated TEXT
                        , PRIMARY KEY(original, language)) WITHOUT ROWID;
INSERT INTO translations VALUES ('name', 'ru', 'название');
-- etc.

Масштабируемый, легче проверять и обновлять данные, позволяющие получить только соответствующие биты, работать лучше и т. д.

22
задан tshepang 30 November 2013 в 23:07
поделиться

3 ответа

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

  • находится в реальном стабильном состоянии
  • поддерживает стиль записи, похожий на привязку, как Text = {LocText ResAssembly: ResFile: ResKey}
  • работает с механизмом .resx-fallback (например, en-us -> en -> независимая культура)
  • поддерживает форсирование культуры (например, «это должен быть английский язык для всех time ")
  • работает с обычными свойствами зависимостей
  • работает с шаблонами управления
  • может использоваться в XAML (на самом деле: P) без каких-либо дополнительных пространств имен
  • может использоваться в коде для привязки локализованных значений к динамическим сгенерированные элементы управления
  • реализуют INotifyPropertyChanged для расширенного использования
  • поддерживает форматирование строк, например CurrentUICulture (может быть легко изменено)
17
ответ дан 29 November 2019 в 04:06
поделиться

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

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

}
34
ответ дан 29 November 2019 в 04:06
поделиться

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

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

1
ответ дан 29 November 2019 в 04:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: