IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Windows Forms Discussion :

Application localizable et nombre de langues


Sujet :

Windows Forms

  1. #1
    Membre averti

    Homme Profil pro
    Inscrit en
    Octobre 2003
    Messages
    908
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 908
    Points : 447
    Points
    447
    Par défaut Application localizable et nombre de langues
    Salut tout le monde,
    Je suis entrain de m 'entrainer à faire une appli localizable, tout va bien , sauf que je n'arrive pas à trouver le moyen de savoir combien de langue sont disponibles.

    Pour être plus clair, je voudrais faire une combobox avec le nom des langues disponibles pour que l'utilisateur puisse choisir.

    Merci d'avance

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 753
    Points
    39 753
    Par défaut
    Tu as utilisé le système de localisation standard de Windows Forms, avec des assemblies satellites ?

    Dans ce cas, il y a 2 méthodes possibles :
    • Parcourir toutes les cultures existantes (avec CultureInfo.GetCultures(CultureTypes.AllCultures)) et vérifier si une chaine spécifique existe dans les ressources pour cette culture (simple mais un peu lent)
    • Parcourir les sous-répertoires de ton appli et vérifier la présence de l'assembly satellite :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
              // Enumère les cultures disponibles
              private static ReadOnlyCollection<CultureInfo> GetAvailableCultures()
              {
                  List<CultureInfo> list = new List<CultureInfo>();
       
                  string startupDir = Environment.CurrentDirectory;
                  Assembly asm = AssemblyManager.GetEntryAssembly();
       
                  CultureInfo neutralCulture = CultureInfo.InvariantCulture;
                  if (asm != null)
                  {
                      NeutralResourcesLanguageAttribute attr = Attribute.GetCustomAttribute(asm, typeof(NeutralResourcesLanguageAttribute)) as NeutralResourcesLanguageAttribute;
                      if (attr != null)
                          neutralCulture = CultureInfo.GetCultureInfo(attr.CultureName);
                  }
                  list.Add(neutralCulture);
       
                  if (asm != null)
                  {
                      string baseName = asm.GetName().Name;
                      foreach (string dir in Directory.GetDirectories(startupDir))
                      {
                          // On vérifie que le nom du répertoire correspond à une culture valide
                          DirectoryInfo dirinfo = new DirectoryInfo(dir);
                          CultureInfo tCulture = null;
                          try
                          {
                              tCulture = CultureInfo.GetCultureInfo(dirinfo.Name);
                          }
                          // Ce n'est pas une culture valide : on ignore l'exception et on passe
                          // au répertoire suivant 
                          catch (ArgumentException)
                          {
                              continue;
                          }
       
                          // On vérifie que le répertoire contient des assemblies satellites
                          if (dirinfo.GetFiles(baseName + ".resources.dll").Length > 0)
                          {
                              list.Add(tCulture);
                          }
       
                      }
                  }
                  return list.AsReadOnly();
              }

  3. #3
    Membre averti

    Homme Profil pro
    Inscrit en
    Octobre 2003
    Messages
    908
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 908
    Points : 447
    Points
    447
    Par défaut
    merci tomlev,

    J'utilise en effet les assemblies satellites et je vais prendre ta seconde méthode qui est plus adaptée.

    Aller hop je me met a la "convertir" en pascal

    Merci encore

  4. #4
    Membre averti

    Homme Profil pro
    Inscrit en
    Octobre 2003
    Messages
    908
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 908
    Points : 447
    Points
    447
    Par défaut
    par contre si cela ne te dérange pas je serais bien preneur d'un ou deux commentaires en plus, voir une petite explication pour que je comprenne bien le code.

    Merci d'avance

  5. #5
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 753
    Points
    39 753
    Par défaut
    1. On vérifie s'il existe un NeutralResourcesLanguageAttribute défini sur l'assembly. Cet attribut indique la culture "par défaut" utilisée dans l'assembly principal. Si oui, on ajoute la culture correspondante dans la liste.
    2. On récupère le nom de l'assembly principal, qui est le nom de base des assemblies satellites
    3. On parcourt les sous répertoires. Pour chacun, on vérifie si son nom correspond à une culture (par exemple "fr", "en-US", etc...)
    4. Si c'est le cas, on regarde s'il contient un fichier "<nom de l'assembly>.resources.dll"
    5. Si oui, on ajoute la culture à la liste

  6. #6
    Membre averti

    Homme Profil pro
    Inscrit en
    Octobre 2003
    Messages
    908
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 908
    Points : 447
    Points
    447
    Par défaut
    Merci

  7. #7
    Rédacteur
    Avatar de Greybird
    Inscrit en
    Juin 2002
    Messages
    673
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 673
    Points : 1 271
    Points
    1 271
    Par défaut
    Bonjour,

    Le Environment.CurrentDirectory est risqué, car le CurrentDirectory peut bouger durant l'exécution. Je pense que http://faqcsharp.developpez.com/inde...st#syst_appdir est plus approprié

    Juste une petite précision au passage : ce code ne fonctionne pas si les assemblies satellites sont installés dans le GAC.
    Plus anecdotique, il ne prend pas en compte non plus les types de chemins
    [application base] / [culture] / [assembly name] / [assembly name].dll
    Je ne suis pas sûr non plus qu'il gère les privatePath.
    Cela reste néanmoins tout à fait approprié pour le cas classique de déploiement.


    Plus d'info sur la résolution d'assemblies et les chemins recherchés :
    http://msdn.microsoft.com/en-us/library/15hyw9x3.aspx

    Cordialement,

  8. #8
    Membre averti

    Homme Profil pro
    Inscrit en
    Octobre 2003
    Messages
    908
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 908
    Points : 447
    Points
    447
    Par défaut
    Greybird,

    Tu proposes d'utiliser quelle méthode alors?

  9. #9
    Rédacteur
    Avatar de Greybird
    Inscrit en
    Juin 2002
    Messages
    673
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 673
    Points : 1 271
    Points
    1 271
    Par défaut
    Si tu maîtrises l'application, tu devrais maîtriser la façon dont sont déployés les assemblies non ?
    Assure-toi juste que le code soit en correspondance avec ce déploiement.
    Il est en effet relativement raisonnable de penser qu'un utilisateur ne déplacera pas les assemblies pour les réorganiser.

    En dehors de ma remarque sur le CurrentDirectory, qu'il ne faut pas utiliser à mon sens, les autres remarques sont destinées à préciser la réponse pour le cas où quelqu'un d'autre viendrait à utiliser ce code et tomberait dans un cas non géré.

  10. #10
    Membre averti

    Homme Profil pro
    Inscrit en
    Octobre 2003
    Messages
    908
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 908
    Points : 447
    Points
    447
    Par défaut
    Désolé je suis débutant en Dot Net.

    Je pensais, vu ton message précédent, que tu avais une meilleure méthode.

    Désolé

  11. #11
    Rédacteur
    Avatar de Greybird
    Inscrit en
    Juin 2002
    Messages
    673
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 673
    Points : 1 271
    Points
    1 271
    Par défaut
    A mon sens, et sans catalogue de langues gérées, il n'y a pas de méthodes rapides et complètes.

    Une méthode complète pourrait être de se baser sur les méthodes de chargement d'assemblies (Assembly.Load/Assembly.ReflectionOnlyLoad), mais elle imposerait de parcourir l'ensemble des cultures, ce qui en fait un bon nombre. De plus, les cultures peuvent prendre plusieurs formes (cultures neutres ou spécifiques par exemple), ce qui rajoute encore à la complexité.

  12. #12
    Membre averti

    Homme Profil pro
    Inscrit en
    Octobre 2003
    Messages
    908
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 908
    Points : 447
    Points
    447
    Par défaut
    Et je pose surement une question bête, mais comment puis-je faire un "catalogue de langues" ?

  13. #13
    Rédacteur
    Avatar de Greybird
    Inscrit en
    Juin 2002
    Messages
    673
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 673
    Points : 1 271
    Points
    1 271
    Par défaut
    A peu près d'autant de manières que tu le souhaites.

    Il peut être en dur dans l'application, ça peut être un fichier à côté de l'application (app.config, fichier plat, xml, autre format,...), une bdd, un répertoire avec un fichier par langue disponible, etc

    Le tout étant que quelque part tu aies l'information sur les langues que tu gères. Au lancement de l'application, tu charges ce catalogue, et tu propose à l'utilisateur les langues dans la combo.

  14. #14
    Membre averti

    Homme Profil pro
    Inscrit en
    Octobre 2003
    Messages
    908
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 908
    Points : 447
    Points
    447
    Par défaut
    ok parfait je me penche sur cette méthode alors

  15. #15
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 753
    Points
    39 753
    Par défaut
    Citation Envoyé par Greybird Voir le message
    Le Environment.CurrentDirectory est risqué, car le CurrentDirectory peut bouger durant l'exécution. Je pense que http://faqcsharp.developpez.com/inde...st#syst_appdir est plus approprié
    Exact...
    On peut aussi utiliser Process.GetCurrentProcess().StartInfo.WorkingDirectory, ça évite de faire un truc crado avec un Substring sur la ligne de commande...

    Citation Envoyé par Greybird Voir le message
    Juste une petite précision au passage : ce code ne fonctionne pas si les assemblies satellites sont installés dans le GAC.
    Plus anecdotique, il ne prend pas en compte non plus les types de chemins
    [application base] / [culture] / [assembly name] / [assembly name].dll
    Je ne suis pas sûr non plus qu'il gère les privatePath.
    Exact à nouveau...
    La solution la plus générique serait sans doute la première que j'ai suggérée : énumérer les cultures existantes et tester si les ressources sont définies pour cette culture (avec le ResourceManager). Mais je sais pour l'avoir déjà utilisée qu'elle est assez lente (quelques dizaines, voire centaines, de cultures à tester, avec recherche d'assembly satellite à chaque fois...)

    Donc au final, le plus simple est sans doute d'utiliser un simple fichier catalogue

  16. #16
    Rédacteur
    Avatar de Greybird
    Inscrit en
    Juin 2002
    Messages
    673
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 673
    Points : 1 271
    Points
    1 271
    Par défaut
    Citation Envoyé par tomlev Voir le message
    Exact...
    On peut aussi utiliser Process.GetCurrentProcess().StartInfo.WorkingDirectory, ça évite de faire un truc crado avec un Substring sur la ligne de commande...
    Non, les assemblies sont résolus par rapport à l'application base, et par défaut, ce n'est pas le working directory, mais le répertoire de l'assembly contenant la méthode Main.
    Pour Windows Forms, le plus simple est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Application.StartupPath
    qui est indiqué en commentaire dans la FAQ.

  17. #17
    Membre averti

    Homme Profil pro
    Inscrit en
    Octobre 2003
    Messages
    908
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 908
    Points : 447
    Points
    447
    Par défaut
    GAC, c'est pour le garbage collector ?

  18. #18
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 753
    Points
    39 753
    Par défaut
    Citation Envoyé par rvzip64 Voir le message
    GAC, c'est pour le garbage collector ?
    Global Assembly Cache

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Écriture littérale d'un nombre en langue arabe
    Par bastion dans le forum Delphi
    Réponses: 6
    Dernier message: 05/02/2015, 10h04
  2. Nombre de langues dans un document
    Par November-Oscar dans le forum VBA Word
    Réponses: 6
    Dernier message: 30/03/2012, 20h33
  3. [WD-2003] Compte le nombre de langue dans un document
    Par November-Oscar dans le forum VBA Word
    Réponses: 2
    Dernier message: 22/03/2012, 19h34
  4. Réponses: 1
    Dernier message: 30/01/2007, 09h10

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo