2015-03-18 3 views
0

Любой другой подход, чем тот, который я предлагаю здесь, приветствуется.Как загрузить ResourceDictionary по культуре

У меня есть проект, где я пытаюсь управлять локализацией с использованием ресурсных словарей XAML. Для того, чтобы избежать необходимости осуществлять локализацию нагрузку на всех мои кодовых-опережать файлы, я написал следующий конвертер:

public class LocalizationConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     string filePrefix = value as string; 

     string language; 

     // Filter so only supported languages are let through 
     switch (culture.Name.Substring(0, 2)) 
     { 
      case "da": 
       language = "da"; 
       break; 

      default: 
       language = "en"; 
       break; 
     } 

     return filePrefix + "." + language + ".xaml"; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 

Как я пишу в XAML для загрузки словаря языка, давая файл префикс в качестве значения?

ответ

0

Ok. В итоге я использовал статический метод для загрузки моей локализации. Вот метод:

/// <summary> 
/// Loads localization based on culture. 
/// </summary> 
/// <param name="dictionary">The dictionary to load localization to</param> 
/// <param name="basePath">The base path of the localization files. See remarks for further info.</param> 
/// <param name="cultureInfo">Culture to load localization for.</param> 
/// <remarks> 
/// The loaded localization file will be <code>basenameLocalization.languagecode.xaml</code> 
/// (e.g. <code>MainWindowLocalization.de.xaml</code>), or <code>basenameLocalization.languagecode.xaml</code> 
/// for the default localization. 
/// </remarks> 
internal static void ReplaceLocalization(
    ResourceDictionary dictionary, 
    string basePath, 
    CultureInfo cultureInfo) 
{ 
    ResourceDictionary dict = new ResourceDictionary(); 

    // Clean out old localization 
    ResourceDictionary oldLocalization = null; 
    foreach (ResourceDictionary d in dictionary.MergedDictionaries) 
    { 
     if (d.Source.OriginalString.StartsWith(basePath + "Localization.")) 
     { 
      oldLocalization = d; 
     } 
    } 
    if (oldLocalization != null) 
    { 
     dictionary.MergedDictionaries.Remove(oldLocalization); 
    } 

    // Get thee language 
    string language = ""; 
    if (cultureInfo.Name != null) 
    { 
     // We only need to look at the first two characters to determine language 
     language = cultureInfo.Name.Substring(0, 2); 
    } 
    bool defaultLanguage = false; 

    // Filter languages such that only supported languages are loadable, 
    // and any other defaults to the default/neutral language. 
    switch (language) 
    { 
     case "da": 
      break; 

     default: 
      defaultLanguage = true; 
      break; 
    } 

    // Construct the URI 
    string uri; 
    if (defaultLanguage) 
    { 
     uri = basePath + "Localization.xaml"; 
    } 
    else 
    { 
     uri = basePath + "Localization." + language + ".xaml"; 
    } 

    // Load new dictionary 
    dict.Source = new Uri(uri, UriKind.Relative); 
    dictionary.MergedDictionaries.Add(dict); 
} 

Это также хорошо подходит для изменения языка во время выполнения.

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

2

Первый этап - выгрузить текущий словарь ресурсов языка, иначе у вас будет множество объединенных ресурсных словарей, которые ничего не делают.

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

Language files

Теперь рассмотрим следующий метод:

public static void ReplaceLanguage(Uri source) 
    { 
     //The name of the folder where the languages are contained (could be a parameter) 
     string folder = "languages"; 

     if (source == null) 
      return; 

     ResourceDictionary dictionary; 

     try 
     { 
      dictionary = (ResourceDictionary)Application.LoadComponent(source); 
     } 
     catch (IOException) 
     { 
      //resource file doesn't exist. 
      return; 
     } 

     //Remove current resource from the merged dictionaries 
     var currentResource = Application.Current.Resources.MergedDictionaries.FirstOrDefault(x => x.Source != null && x.Source.ToString().Contains(folder)); 

     if (currentResource != null) 
      Application.Current.Resources.MergedDictionaries.Remove(currentResource); 

     //Add the new resource to the dictionary 
     Application.Current.Resources.MergedDictionaries.Add(dictionary); 
    } 

Что это метод:

  1. Загружает ресурсный словарь из источника URI.
  2. Находит и удаляет текущий словарь языка на основе имени папки, что он содержится внутри.
  3. Добавляет новый словарь в список объединенных словарей.

Чтобы получить Uri для языкового файла, вы могли бы сделать что-то вроде этого:

Uri languagePath = new Uri(string.Format("/YourAppNamespace;component/resources/languages/{0}.xaml", language), UriKind.Relative); 

Приведенный выше код предполагает, что ваши языковые файлы именуются как de.xaml или эн. xaml.

Все, что вам нужно сделать, как только у вас есть Uri, вызывает ReplaceLanguage.

+0

Это на самом деле довольно близко к тому, что я делал. См. Мой ответ через мгновение. – beruic

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