2009-02-16 5 views
22

Я разрабатываю многоязычное приложение, использующее файлы .resx.Программный способ получения всех доступных языков (в сборочных сборках)

У меня есть несколько файлов, таких как GlobalStrings.resx, GlobalStrings.es.resx, GlobalStrings.en.resx и т. Д. Когда я хочу использовать это, мне просто нужно установить Thread.CurrentThread.CurrentCulture.

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

comboLanguage.Items.Add(CultureInfo.GetCultureInfo("en")); 
comboLanguage.Items.Add(CultureInfo.GetCultureInfo("es")); 

Я попытался с

cmbLanguage.Items.AddRange(CultureInfo.GetCultures(CultureTypes.UserCustomCulture)); 

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

Есть ли способ получить только поддерживаемые языки?

ответ

1

Используя то, что Rune Grimstad сказал, что я в конечном итоге с этим:

string executablePath = Path.GetDirectoryName(Application.ExecutablePath); 
string[] directories = Directory.GetDirectories(executablePath); 
foreach (string s in directories) 
{ 
    try 
    { 
     DirectoryInfo langDirectory = new DirectoryInfo(s); 
     cmbLanguage.Items.Add(CultureInfo.GetCultureInfo(langDirectory.Name)); 
    } 
    catch (Exception) 
    { 

    } 
} 

или другой способ

int pathLenght = executablePath.Length + 1; 
foreach (string s in directories) 
{ 
    try 
    { 
     cmbLanguage.Items.Add(CultureInfo.GetCultureInfo(s.Remove(0, pathLenght))); 
    } 
    catch (Exception) 
    { 

    } 
} 

Я все еще не думаю, что это хорошая идея ...

+0

Я думаю, что это единственное решение, которое мы получили. Я в одной лодке. – Jippers

+0

Не могли бы вы также получить каталоги ресурсов, которые были развернуты ваши зависимости (если они есть)? Таким образом, вы можете столкнуться с некоторыми культурами, которые вы не поддерживаете, но некоторые из ваших зависимостей. –

2

Я не уверен в получении языков, возможно, вы можете сканировать папку установки для dll-файлов, но установка языка на неподдерживаемый язык не должна быть проблемой.

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

До тех пор, пока вы сами управляете приложением, вы можете просто сохранить доступные языки в настройках приложения. Просто через запятую, строка с именами культуры должно хватить: «еп, эс»

37

Вы можете запрограммировать список культур, доступных в вашей заявке

// Pass the class name of your resources as a parameter e.g. MyResources for MyResources.resx 
ResourceManager rm = new ResourceManager(typeof(MyResources)); 

CultureInfo[] cultures = CultureInfo.GetCultures(CultureTypes.AllCultures); 
foreach (CultureInfo culture in cultures) 
{ 
    try 
    { 
     ResourceSet rs = rm.GetResourceSet(culture, true, false); 
     // or ResourceSet rs = rm.GetResourceSet(new CultureInfo(culture.TwoLetterISOLanguageName), true, false); 
     string isSupported = (rs == null) ? " is not supported" : " is supported"; 
     Console.WriteLine(culture + isSupported); 
    } 
    catch (CultureNotFoundException exc) 
    { 
     Console.WriteLine(culture + " is not available on the machine or is an invalid culture identifier."); 
    } 
} 
+0

Обратите внимание, что 'GlobalStrings.resx' будет обнаружен в' InvariantCulture'. – Hans

+5

Не будет ли это по существу принудительно загружать все спутниковые сборки? –

+0

@TaylorBuchanan, возможно, после этого может вызвать ReleaseAllResources (https://msdn.microsoft.com/en-us/library/system.resources.resourcemanager.releaseallresources(v=vs.110).aspx), а затем снова загрузить конкретный ресурс –

1

на основе ответа на @ Ханс-holzbart, но фиксировано, чтобы не возвращать InvariantCulture слишком и заворачивают в многоразовый способ:

public static IEnumerable<CultureInfo> GetAvailableCultures() 
{ 
    List<CultureInfo> result = new List<CultureInfo>(); 

    ResourceManager rm = new ResourceManager(typeof(Resources)); 

    CultureInfo[] cultures = CultureInfo.GetCultures(CultureTypes.AllCultures); 
    foreach (CultureInfo culture in cultures) 
    { 
    try 
    { 
     if (culture.Equals(CultureInfo.InvariantCulture)) continue; //do not use "==", won't work 

     ResourceSet rs = rm.GetResourceSet(culture, true, false); 
     if (rs != null) 
     result.Add(culture); 
    } 
    catch (CultureNotFoundException) 
    { 
     //NOP 
    } 
    } 
    return result; 
} 

, используя этот метод, вы можете получить список строк для добавления некоторые ComboBox со следующим:

public static ObservableCollection<string> GetAvailableLanguages() 
{ 
    var languages = new ObservableCollection<string>(); 
    var cultures = GetAvailableCultures(); 
    foreach (CultureInfo culture in cultures) 
    languages.Add(culture.NativeName + " (" + culture.EnglishName + " [" + culture.TwoLetterISOLanguageName + "])"); 
    return languages; 
} 
4

Это будет один из раствора на основе следующего утверждения:
Каждый спутник сборки для конкретного языка называется то же, но лежит в подпапке, названной в честь конкретной культуры, например. fr или fr-CA.

public IEnumerable<CultureInfo> GetSupportedCulture() 
{ 
    //Get all culture 
    CultureInfo[] culture = CultureInfo.GetCultures(CultureTypes.AllCultures); 

    //Find the location where application installed. 
    string exeLocation = Path.GetDirectoryName(Uri.UnescapeDataString(new UriBuilder(Assembly.GetExecutingAssembly().CodeBase).Path)); 

    //Return all culture for which satellite folder found with culture code. 
    return culture.Where(cultureInfo => Directory.Exists(Path.Combine(exeLocation, cultureInfo.Name))); 
} 
+1

Это решение работает в моем проекте ASP.net MVC. Спасибо !! –

+0

@JeffT. Да, это очень общий подход, я использую этот подход для нашего проекта WPF! –

+0

Обратите внимание, что это также возвращает инвариантный язык. – ooorndtski

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