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 :

Appli C# multi-langue


Sujet :

Windows Forms

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    160
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Novembre 2003
    Messages : 160
    Points : 89
    Points
    89
    Par défaut Appli C# multi-langue
    J'aimerais que mon appli soit multilangue (anglais/francais, quoi). Ds ttes mes Form, je fais donc :

    - Localizable = true,
    - Language English (US) : je change ts les labels etc... en Anglais
    - Language French (FR) : idem en Francais.

    Lorsque je change la langue, je fais :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Thread.CurrentThread.CurrentCulture = Context.FrenchCulture;
    ou bien

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Thread.CurrentThread.CurrentCulture = Context.EnglishCulture;
    FrenchCulture et EnglishCulture etant des instances CultureInfo initialisés avec les strings qui vont bien, respectivement "en-US" et "fr-FR".

    Pourtant, l'interface ne "percute" pas. Aucun changement. L'article du site propose un moyen me paraissant tres peu satisfaisant, car je dois affecter TOUS mes controles à la main. Bref, une horreur.

    Qqn a une idée? Merci d'avance ...

  2. #2
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Points : 13 314
    Points
    13 314
    Par défaut
    Citation Envoyé par hobotalker
    Pourtant, l'interface ne "percute" pas. Aucun changement.
    Qu'attends tu comme changement ?

    La changement de culture modifie normalement :

    - la présentation des valeurs numériques (. & ,)
    - des dates
    - des affichages en devise (type currency)

    Quel est ton soucis ici ?
    Sinon, pour le multilinguisme, une solution assez simple est de mettre toutes les chaines à traduire dans un fichier (xml ou autre) voire une table et d'utiliser comme clef d'accés un hashcode calculé sur la valeur de chaine utiisé en développment (français semble-t-il dans ton cas), et écrire une classe qui "browse" le projet une fois pour toute (pour calculer les valeurs de hash dans la langue de référence), puis une autre qui charge les chaines qui-vont-bien à l'exécution.

    Ta question semble un peu trop généraliste ou c'est moi qui ne pige pas.

    Je ne réponds pas aux questions techniques par MP ! Le forum est là pour ça...


    Une réponse vous a aidé ? utiliser le bouton

    "L’ennui dans ce monde, c’est que les idiots sont sûrs d’eux et les gens sensés pleins de doutes". B. Russel

  3. #3
    Rédacteur
    Avatar de The_badger_man
    Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2005
    Messages
    2 745
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 745
    Points : 8 538
    Points
    8 538
    Par défaut
    et avec
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    System.Threading.Thread.CurrentThread.CurrentUICulture = new CultureInfo(culture);
    Les règles du forum
    Le trio magique : FAQ + Cours + fonction rechercher
    Mes articles
    Pas de questions par messages privés svp

    Software is never finished, only abandoned.

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    160
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Novembre 2003
    Messages : 160
    Points : 89
    Points
    89
    Par défaut
    Désolé pour le manque de clarté.

    Normalement, VS 2005 permet d'éditer en mode Design ttes tes fenetres en 2 modes differents. Par exemple, ma Form FrmMain est editable en design en-US et en design fr-FR.

    Ainsi, je renomme ts mes labels, titres de grpbox, etc... en mode Design. Des fichiers ressources sont générés pour chaque langue supportée et il serait donc possible de signifier à l'interface sur lequel de ces fichiers ressources s'appuyer pour afficher les textes ds la langue appropriée.

    Ici, meme qd je change le CurrentCulture (ou même le CurrentUICulture), rien ne se passe, mes grpbox gardent leurs titres anglais, mes labels idem ... Faut-il réinstancier la fenetre?

    Bref, ce systeme m'affranchit de coder la classe que tu me decris. Evidemment que l'on peut faire comme ca, mais ce n'est pas le sujet. Je cherche ici a tirer profit d'un mecanisme déjà implémenté pour nous... Surtout que le gain de temps est non negligeable, au fur et a mesure des differents projets.

    J'espere avoir été assez clair cette fois ci, merci de m'avoir répondu.

  5. #5
    Rédacteur
    Avatar de The_badger_man
    Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2005
    Messages
    2 745
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 745
    Points : 8 538
    Points
    8 538
    Par défaut
    Où places-tu ce code ?
    Les règles du forum
    Le trio magique : FAQ + Cours + fonction rechercher
    Mes articles
    Pas de questions par messages privés svp

    Software is never finished, only abandoned.

  6. #6
    Membre émérite

    Inscrit en
    Novembre 2006
    Messages
    128
    Détails du profil
    Informations personnelles :
    Âge : 42

    Informations forums :
    Inscription : Novembre 2006
    Messages : 128
    Points : 2 624
    Points
    2 624
    Par défaut
    Dans ta Form, tu mets Localizable à true et tu mets Language à "English (United States)". Tu mets alors le Text que tu veux dans tes Labels. Tu changes la langue et tu mets "Français (France)". Tu changes tes labels et c'est bon. Tu peux même avoir des tailles ou des positions de contrôles différentes suivant la culture. Si tu veux faire cela pour tu texte mis dans ton code, il faut que tu te crée un fichier de ressources (par défaut) puis que tu te crée un fichier de ressource du même nom avec ".fr.resx" au lieu de ".resx" (pour la culture française. Tu mets la même clé que dans ton fichier de base. Tu traduits le texte et c'est bon.

  7. #7
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Points : 13 314
    Points
    13 314
    Par défaut
    Citation Envoyé par Matthieu MEZIL
    Dans ta Form, tu mets Localizable à true et tu mets Language à "English (United States)". Tu mets alors le Text que tu veux dans tes Labels.
    L'inconvénient de cette méthode est qu'elle suppose (dans les faits) que le développeur gère lui même le multilinguisme, et, dans tous les cas, rend difficile une traduction "en batch" a posteriori, qui est souvent indispensable.

    A l'époque "héroïque " de vB6/VC++6, j'avais adopté cette solution consistant à balayer les contrôle du projet et de calculer une clef qui était le hashcode de la chaîne dans sa langue originale pour faciliter les problème de traduction a posteriori. (je travaillais en Espagne à cette époque, et toutes les appli étaient au moins bilingue (castillan-catalan) voire tri ou quadri ou plus (valencien, galicien, basque).

    Je ne réponds pas aux questions techniques par MP ! Le forum est là pour ça...


    Une réponse vous a aidé ? utiliser le bouton

    "L’ennui dans ce monde, c’est que les idiots sont sûrs d’eux et les gens sensés pleins de doutes". B. Russel

  8. #8
    Membre émérite

    Inscrit en
    Novembre 2006
    Messages
    128
    Détails du profil
    Informations personnelles :
    Âge : 42

    Informations forums :
    Inscription : Novembre 2006
    Messages : 128
    Points : 2 624
    Points
    2 624
    Par défaut
    Oui mais de toute façon, pour résoudre les problèmes de tailles de Label, c'est la seule solution. Après, ce qui est généré en plus, c'est un simple fichier de ressources. Mais il est vrai que pour tester, le traducteur doit pouvoir recompiler la solution.

  9. #9
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    160
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Novembre 2003
    Messages : 160
    Points : 89
    Points
    89
    Par défaut
    @The_badger_man : Le code de changement de CurrentCulture/CurrentUICulture n'est placé à aucun endroit en particulier. Simplement sur les events des controles qui permettent de modifier le parametre de langue de l'appli. Je me demandais s'il fallait absolument le mettre avant l'InitializeComponent(). Si c'est la cas, je touve ca un peu dommage de devoir fermer l'appli pour changer de langue ...

    @Matthieu MEZIL : J'ai fait tt ca, mais je n'arrive pas a switcher l'appli d'une langue a une autre ...

  10. #10
    Rédacteur
    Avatar de The_badger_man
    Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2005
    Messages
    2 745
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 745
    Points : 8 538
    Points
    8 538
    Par défaut
    Met ce code dans ton main avant le chargement de ta premiere form.

    Il faut malheureusement relancer l'appli à chaque fois.
    Tu peux le faire par code avec un Application.restart();
    Les règles du forum
    Le trio magique : FAQ + Cours + fonction rechercher
    Mes articles
    Pas de questions par messages privés svp

    Software is never finished, only abandoned.

  11. #11
    Expert confirmé

    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Septembre 2006
    Messages
    3 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Septembre 2006
    Messages : 3 580
    Points : 5 195
    Points
    5 195
    Par défaut
    Personnellement, et dans un cadre professionnel... la solution que nous avons
    retenu a été double en fonction du contexte d'utilisation...

    Dans un projet ou nous savions que la langue serait francais ou anglais,
    nous sommes passés par la solution des ressources (éditées sous VS)

    Pour un autre projet ou nous avions besoin d'un basculement dynamique
    entre plusieurs langues dont certaines demandant l'intervention d'un traducteur,
    nous avons mis en place un fichier de langue...

    Voici un exemple d'item utilisé :

    <item name="_traduireOui">
    <trad lang="FR" trad="Oui"\>
    <trad lang="UK" trad="Yes"\>
    <\item>

    etc...

    Ainsi, on remarque que l'item est identifié par une chaine canonique...

    Dans le code, on utilise des fonctions maisons de traduction genre :

    TranslateForm(Form);
    TranslateMenu(Menu);
    TranslateText(String text);

    etc...

    Ainsi, notre librairie de traduction est independante et facilement reutilisable.
    De plus, l'utilisation de fichiers XML externe facilite la traduction par des
    intervenants exterieurs et distants de notre société

    Voila mon opinion sur les 2 approches les plus "rationnelles" selon moi

    The Monz, Toulouse
    The Monz, Toulouse
    Expertise dans la logistique et le développement pour
    plateforme .Net (Windows, Windows CE, Android)

  12. #12
    Membre émérite

    Inscrit en
    Novembre 2006
    Messages
    128
    Détails du profil
    Informations personnelles :
    Âge : 42

    Informations forums :
    Inscription : Novembre 2006
    Messages : 128
    Points : 2 624
    Points
    2 624
    Par défaut
    @Matthieu MEZIL : J'ai fait tt ca, mais je n'arrive pas a switcher l'appli d'une langue a une autre ...

    C'est parce que tu dois faire ceci pour changer de langue :
    Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("en");

  13. #13
    Membre régulier
    Inscrit en
    Mars 2002
    Messages
    118
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 118
    Points : 70
    Points
    70
    Par défaut
    Bonjour !

    Est-ce que quelqu'un classe de ce type est déjà disponible? Quelque chose de simple et compréhensible qui va lire les informations relatives a une langues dans un fichier XML et puis les affiches.

    Merci de votre aide !

    Martin

  14. #14
    Expert confirmé

    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Septembre 2006
    Messages
    3 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Septembre 2006
    Messages : 3 580
    Points : 5 195
    Points
    5 195
    Par défaut
    Beh, la classe, tu te la fais AUTOMATIQUEMENT avec Visual Studio et XSD.exe

    Bon, j'explique rapidemment

    Tu prends un editeur de base (ou Vs)
    tu crées ton fichier XML comme tu voudrais qu'il soit.. (attention, mets
    juste l'ensemble des tags que tu veux... avec attributs et tout et tout...

    Menu XML de VS (ou tu as ouvert ton fichier xml) -> Create Schema
    (ensuite, tu sauvegardes ton schéma xsd

    Ligne de commande : xsd.exe /c /language:cs tonFichier.xsd

    et voila, tu auras la classe pour lire le bazar....

    Apres, pour recuperer dans ta classe le contenu de ton fichier xml
    tu fais un truc du genre (dans mon exemple, traduction est le nom de
    la classe générée avec xsd

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     XmlSerializer xml = new XmlSerializer(typeof(traduction));
                StreamReader reader = new StreamReader(@"d:\perso\DotNet\traduction.Xml");
                trad = xml.Deserialize(reader) as traduction;
    et voila... dans ton objet, tu as toute l'arborescence de ton xml...
    t'as plus qu'à balayé en fonction de ta structure

    Ca devrait aller quand meme ? non ?

    The Monz, TOulouse
    The Monz, Toulouse
    Expertise dans la logistique et le développement pour
    plateforme .Net (Windows, Windows CE, Android)

  15. #15
    Expert confirmé

    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Septembre 2006
    Messages
    3 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Septembre 2006
    Messages : 3 580
    Points : 5 195
    Points
    5 195
    Par défaut
    et dans ma grande "bonté".. voici un exemple

    (code + exe)

    Pour le faire fonctionner, copie juste traduction.xml dans c:\

    et voila... ca devrait aider j'espère tout le monde

    The Monz, Toulouse
    The Monz, Toulouse
    Expertise dans la logistique et le développement pour
    plateforme .Net (Windows, Windows CE, Android)

  16. #16
    Membre régulier
    Inscrit en
    Mars 2002
    Messages
    118
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 118
    Points : 70
    Points
    70
    Par défaut
    Bonjour !

    Je comprends très bien ton exemple, et merci! Cependant, tu changes la valeur des composants à l'extérieur du InitializeComponent qui lui exécute un this.SuspendLayout(); qui empêche la fenêtre de se dessiner et à la fin un this.ResumeLayout(false); et this.PerformLayout(); qui force le dessinage de la fenêtre.

    Dans le meilleur des mondes, afin d'éviter un sautillement de l'affichage (dans les fenêtre lourde), il faudrait que le tout soit exécuté dans InitializeComponent. Cependant, nous ne devons pas modifier le contenue de cette méthode puis que le FormDesigner la modifie... Je vais devoir trouver une solution a ce problème.

  17. #17
    Expert confirmé

    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Septembre 2006
    Messages
    3 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Septembre 2006
    Messages : 3 580
    Points : 5 195
    Points
    5 195
    Par défaut
    attends, l'exemple etait juste pour te montrer le processus entre la création du XML et l'utilisation de la classe générée par XSD...

    Maintenant, une fois que tu as fait InitializeComponent() et que tu as
    chargé tes traductions XML dans la classe auto-générée, il te faut à la mimine
    appeler des méthodes à toi du genre :

    TranslateWindowForm(myForm);

    En voici un exemple sommaire

    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
    47
    48
    49
    50
    51
    52
    53
        private traductionItem[] itemField;
        private Dictionary<string, string> items = null;
        private string lang;
     
        public void InitTranslator(string language)
        {
            if (items == null)
            {
                items = new Dictionary<string, string>();
            }
            else
            {
                items.Clear();
            }
     
            // built the dictonnary with the correct language...
            this.lang = language;
            for (int i = 0; i < this.item.Length; ++i)
            {
                string key = item[i].name;
                string value = item[i].name;
                for(int j = 0; j < item[i].trad.Length;++j)
                {
                    if (item[i].trad[j].lang == language)
                    {
                        value = item[i].trad[j].text;
                        break;
                    }
                }            
                items.Add(key, value);
            }
     
        }
     
        public void TranslateWindow(Form f)
        {
            foreach (Control c in f.Controls)
            {
                TranslateControl(c);
            }        
        }
     
        private void TranslateControl(Control c)
        {
            c.Text = items[c.Name];
            if (c.Controls.Count > 0)
            {
                foreach (Control a in c.Controls)
                {
                    TranslateControl(a);
                }
            }
        }
    En gros, je crée un dictionnaire pour faciliter la recherche. Dans ce dictionnaire, j'ai comme clé, le nom canonique de l'item et comme valeur,
    sa traduction dans la langue qui va bien (passée en paramètre)

    Ensuite, je fais une fonction recursive qui scanne tous les controles de ta
    form et ainsi de suite et qui les traduits

    La meme fonction serait à écrire pour les menus.. et autres éléments auxquels je ne pense pas...

    ainsi, dans ton code, tu n'auras plus qu'à faire un truc du genre :

    Translator.TranslateForm(this);
    et voila, le tour est joué ...

    Apres, je me suis basé dans mon exemple sur le nom du composant plutot que sur son texte, mais rien ne t'empeche d'utiliser le Tag d'un composant...
    (je prefere eviter d'utiliser le texte du composant il vaut mieux que la clé utilisé pour trouver la traduction ne soit pas modifiée ou altérée en cas de basculement de traduction en cours d'application, ca pourrait poser soucis
    de l'avoir perdue


    Voila, je pense que c suffisant ? résolu ?

    The Monz, Toulouse
    The Monz, Toulouse
    Expertise dans la logistique et le développement pour
    plateforme .Net (Windows, Windows CE, Android)

  18. #18
    Membre régulier
    Inscrit en
    Mars 2002
    Messages
    118
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 118
    Points : 70
    Points
    70
    Par défaut
    Salut !

    Je comprends très bien ce que tu fais, cependant, je reste convaincu que la modification des Text des composants doit être faite dans le InitializeComponent afin de ne pas créer un espèce de scintillement de l'écran. Non ?

    Martin

  19. #19
    Expert confirmé

    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Septembre 2006
    Messages
    3 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Septembre 2006
    Messages : 3 580
    Points : 5 195
    Points
    5 195
    Par défaut
    non... c tout à fait illusoire de croire cela...

    Et meme si tu avais un "scintillement" que je n'ai JAMAIS remarqué, tu ne l'aurais qu'une fois, le temps de mettre à jour les textes....

    Et tu peux rajouter dans mes methodes des SuspendLayout();

    The Monz, Toulouse
    The Monz, Toulouse
    Expertise dans la logistique et le développement pour
    plateforme .Net (Windows, Windows CE, Android)

  20. #20
    Membre régulier
    Inscrit en
    Mars 2002
    Messages
    118
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 118
    Points : 70
    Points
    70
    Par défaut
    Tu devrais essaye de faire des tests avec des fenêtre lourde... TreeView, Dropdownlist, etc. Il y a une grosse différence dans les performances sur des configurations moyennes si tu fais le tout entre le Suspend et PerformLayout...

Discussions similaires

  1. Appli Multi langue
    Par Piercing dans le forum EDI/Outils
    Réponses: 9
    Dernier message: 13/07/2011, 10h48
  2. [iOS 4.x] Appli Multi langue
    Par Feanorin dans le forum Objective-C
    Réponses: 1
    Dernier message: 07/01/2011, 11h49
  3. Appli MFC multi langue
    Par youda dans le forum MFC
    Réponses: 5
    Dernier message: 04/02/2008, 11h38
  4. [CR][.NET] Rapport multi-langue
    Par Harakor dans le forum SAP Crystal Reports
    Réponses: 4
    Dernier message: 16/02/2005, 17h06
  5. [C#] Multi langue - fichier resource.resx
    Par dacamp dans le forum ASP.NET
    Réponses: 5
    Dernier message: 03/06/2004, 16h25

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