façon d'obtenir toutes Programmatic les langues disponibles (dans les assemblées satellites)

StackOverflow https://stackoverflow.com/questions/553244

Question

Je suis la conception d'une application multilingue utilisant des fichiers .resx.

J'ai quelques fichiers comme GlobalStrings.resx, GlobalStrings.es.resx, GlobalStrings.en.resx, etc. Quand je veux utiliser cela, je dois juste mettre Thread.CurrentThread.CurrentCulture.

Le problème: J'ai un combobox avec toutes les langues disponibles, mais je charger manuellement:

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

Je l'ai essayé avec

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

sans succès. En outre essayé avec tous les éléments CultureTypes, mais je n'obtenir une grande liste avec beaucoup d'autres langues que je ne suis pas à l'aide, ou une liste vide.

Est-il possible d'obtenir que les langues prises en charge?

Était-ce utile?

La solution 5

En utilisant ce que Rune Grimstad dit que je finis avec ceci:

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

    }
}

ou d'une autre façon

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

    }
}

Je ne pense toujours pas que ce soit une bonne idée ...

Autres conseils

Vous pouvez lister les cultures disponibles programatically dans votre application

// 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.");
    }
}

fonction de la réponse par @ hans-holzbart mais fixe pour ne pas retourner le InvariantCulture aussi, et enveloppé dans une méthode réutilisable:

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;
}

en utilisant cette méthode, vous pouvez obtenir une liste de chaînes à ajouter à une zone de liste déroulante avec les éléments suivants:

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;
}

Ce serait l'une des solution sur base de la déclaration suivante:
Chaque ensemble de satellite pour une langue spécifique est le même nom, se trouve dans un sous-dossier portant le nom de la culture spécifique par exemple fr ou 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)));
}

Je ne suis pas sûr d'obtenir les langues, peut-être vous pouvez scanner votre dossier d'installation pour les fichiers dll, mais la définition de votre langue pour une langue non prise en charge ne devrait pas être un problème.

.NET fallback aux ressources neutres de culture si aucun fichier spécifique de la culture peuvent être trouvés afin que vous puissiez en toute sécurité sélectionner les langues non pris en charge.

Tant que vous contrôlez l'application vous-même vous pouvez simplement stocker les langues disponibles dans une application mise en quelque part. Juste une chaîne séparée par des virgules avec les noms de la culture devrait suffire: « en, es »

@ « Ankush Madankar » présente un point de départ intéressant, mais il a deux problèmes: 1) Recherche des ressources aussi des dossiers pour les ressources des assemblées refrenced 2) Doesn trouver la ressource pour le langage d'assemblage de base

Je ne vais pas essayer de résoudre la question 2) mais pour numéro 1) le code doit être

public List<CultureInfo> GetSupportedCultures()
{
    CultureInfo[] culture = CultureInfo.GetCultures(CultureTypes.AllCultures);

    // get the assembly
    Assembly assembly = Assembly.GetExecutingAssembly();

    //Find the location of the assembly
    string assemblyLocation =
        Path.GetDirectoryName(Uri.UnescapeDataString(new UriBuilder(assembly.CodeBase).Path));

    //Find the file anme of the assembly
    string resourceFilename = Path.GetFileNameWithoutExtension(assembly.Location) + ".resources.dll";

    //Return all culture for which satellite folder found with culture code.
    return culture.Where(cultureInfo =>
        assemblyLocation != null &&
        Directory.Exists(Path.Combine(assemblyLocation, cultureInfo.Name)) &&
        File.Exists(Path.Combine(assemblyLocation, cultureInfo.Name, resourceFilename))
    ).ToList();
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top