以编程方式获取所有可用语言(在卫星装配中)

Mat*_*ías 29 .net c# localization cultureinfo

我正在使用.resx文件设计多语言应用程序.

我有一些文件,如GlobalStrings.resx,GlobalStrings.es.resx,GlobalStrings.en.resx等.当我想使用它时,我只需要设置Thread.CurrentThread.CurrentCulture.

问题:我有一个包含所有可用语言的组合框,但我手动加载:

comboLanguage.Items.Add(CultureInfo.GetCultureInfo("en"));
comboLanguage.Items.Add(CultureInfo.GetCultureInfo("es"));
Run Code Online (Sandbox Code Playgroud)

我试过了

cmbLanguage.Items.AddRange(CultureInfo.GetCultures(CultureTypes.UserCustomCulture));
Run Code Online (Sandbox Code Playgroud)

没有任何成功.还尝试了CultureTypes中的所有元素,但是我只获得了一个包含更多我不使用的语言的大列表,或者是一个空列表.

有没有办法只获得支持的语言?

Han*_*art 47

您可以以编程方式列出应用程序中可用的文化

// 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.");
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 这基本上不会强制加载所有卫星组件吗? (6认同)

Geo*_*lis 5

基于@hans-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;
}
Run Code Online (Sandbox Code Playgroud)

使用该方法,您可以使用以下内容获取要添加到某些 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;
}
Run Code Online (Sandbox Code Playgroud)


Mat*_*ías 2

根据 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)
    {

    }
}
Run Code Online (Sandbox Code Playgroud)

或者另一种方式

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

    }
}
Run Code Online (Sandbox Code Playgroud)

我仍然不认为这是一个好主意......