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

C# Discussion :

parcourir les forms d'une application


Sujet :

C#

  1. #1
    Membre expérimenté
    Profil pro
    Mangeur de gauffre
    Inscrit en
    Octobre 2007
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Mangeur de gauffre

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 413
    Par défaut parcourir les forms d'une application
    Bonjour

    Je cherche le meilleur moyen de parcourir l'ensemble des form d'une application afin d'extraire une liste des controls et de leur texte

    Je sais bien entendu parcourir tous les controls d'une form
    Mais est il possible de parcourir toutes les forms de l'application ?

    Merci de votre aide

  2. #2
    Membre expérimenté
    Profil pro
    Mangeur de gauffre
    Inscrit en
    Octobre 2007
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Mangeur de gauffre

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 413
    Par défaut
    Bonjour

    Il y a bien
    Mais ca ne donne que les forms instancieée

    Est il possible a votre avis de parcourir Toutes les form au runtime
    Ou bien dois-je envisager de faire un parseur des les sources du projet ?

    Une alternative serait evidemment d'utiliser un outil existant qui fait ca, mais je n'en ai pas trouvé ?

  3. #3
    Membre émérite Avatar de ctxnop
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2007
    Messages
    858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Morbihan (Bretagne)

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

    Informations forums :
    Inscription : Juillet 2007
    Messages : 858
    Par défaut
    Salut,
    Si tu recherches toutes les forms d'une application, sans se soucier du fait qu'elles soient ou non instanciées et en combien d'exemplaire, c'est que tu recherche toutes les classes qui héritent de System.Windows.Forms.Form.
    Donc utilise la réflexion. Tu parts de l'AppDomain et, pour chaque assembly qui t'intéresse, tu énumères les types (publiques ou non, selon ce que tu cherche), puis tu vérifie si un type hérite de Form.

  4. #4
    Membre expérimenté
    Profil pro
    Mangeur de gauffre
    Inscrit en
    Octobre 2007
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Mangeur de gauffre

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 413
    Par défaut
    Merci ctxnop

    Yes !

    Voici donc ce que ca donne
    Apres je vais broder autour !!

    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
          Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
          Form f = null;
          foreach (Assembly A in assemblies)
          {
            Type[] types = A.GetTypes();
            foreach (Type t in types)
            {
              if (t.IsPublic && t.BaseType == typeof(Form))
              {
                if (t.FullName.Contains("frm"))
                {
                  f = (Form)A.CreateInstance(t.FullName);
                }
              }
            }
          }

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

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Par défaut
    Tu peux utiliser un truc du genre :

    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
              static List<Type> getForms()
            {
                List<Type> list = new List<Type>();
                AppDomain.CurrentDomain.GetAssemblies()
                       .Where(a => a.GlobalAssemblyCache == false)
                       .Where(a => 
                            ((AssemblyProductAttribute)a.GetCustomAttributes(typeof(AssemblyProductAttribute), true).First())
                              .Product == "MyProduct")
                       .ToList()
                       .ForEach(a =>  a.GetTypes()
                            .Where(t => t.IsSubclassOf(typeof(Form)))
                            .ToList()
                            .ForEach( t=> list.Add(t))  
                            );
                return list;
            }
    EDIT : version plus clean.

  6. #6
    Membre expérimenté
    Profil pro
    Mangeur de gauffre
    Inscrit en
    Octobre 2007
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Mangeur de gauffre

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 413
    Par défaut
    Merci bluedeep

    on s'est croisé

  7. #7
    Membre émérite Avatar de ctxnop
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2007
    Messages
    858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Morbihan (Bretagne)

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

    Informations forums :
    Inscription : Juillet 2007
    Messages : 858
    Par défaut
    Faudrait voir aussi à ne pas prendre tous les assembly, ce n'est à mon avis pas ce que tu recherches.
    Le fait est qu'en faisant ainsi, tu charges et parcours une très grande partie du framework .net et donc des milliers de types, ce sera très lent.

    Autres détails :
    - Si tu ne veux que les types publiques, utilise assembly.GetExportedTypes(), tu n'auras que les types publiques donc beaucoup moins d'itérations dans ta boucle et tu n'auras pas à tester le IsPublic.
    - Mieux vaut utiliser IsSubclassOf ou IsAssignableFrom plutôt que de te baser sur BaseType, BaseType te donne le type directement hérité, donc si A hérite de Form, et B de A, B est bien une form, mais ne correspond pas à ton critère.
    - Rien ne garanti que le nom de ton formulaire débute bien par "frm". Si c'est une règle de codage tu trouvera tout ceux qui respectent la règle, mais si certains ont échappé à la règle pour une raison X ou Y, ils ne seront pas trouvés. C'est d'ailleurs une bonne façon de trouver tout ceux qui ne respectent pas la règle.
    - C'est assez dangereux de faire un CreateInstance de chaque formulaire, tu ne sais pas ce que le formulaire provoque à son instanciation. S'il accède à des choses statiques, qu'il initialise des choses dans une base de données, qu'il écrit sur disque, etc... Tu me dira que tout ça sont de mauvaises pratiques, mais ne veut pas dire que tous les formulaires respectent les bonnes pratiques.
    - Si tu es pour faire un CreateInstance, fait un using autour pour disposer le formulaire, et utilise directement Activator.CreateInstance(Type t), c'est plus rapide est c'est de toute façon que ce fini par faire le Assembly.CreateInstance(string typename)

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

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Par défaut
    Citation Envoyé par ctxnop Voir le message
    Faudrait voir aussi à ne pas prendre tous les assembly, ce n'est à mon avis pas ce que tu recherches.
    Le fait est qu'en faisant ainsi, tu charges et parcours une très grande partie du framework .net et donc des milliers de types, ce sera très lent.
    Il peut bypasser cela en testant la propriété GlobalAssemblyCache de l'assembly (et en partant du principe que, à ce stade, ses assemblies ne sont pas dans le GAC).

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

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Par défaut
    Citation Envoyé par olibara Voir le message
    Merci bluedeep

    on s'est croisé
    Oui, mais comme le dit CTXNOP, je ne vois pas pourquoi tu tentes d'instancier chaque form.

    Par ailleurs, les tests fondés sur un pattern spécifique du nom ne me semblent pas une bonne idée.

  10. #10
    Membre expérimenté
    Profil pro
    Mangeur de gauffre
    Inscrit en
    Octobre 2007
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Mangeur de gauffre

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 413
    Par défaut
    Merci pour toutes ces tres judicieuces remarques ctxnop

    Pour le createInstance je ne suis pas certain que ce soit nécessaire
    mais comme l'intention in fine est de browser tous les controls de la form il me semblait que l'intanciation est nécessaire

    Et pour le using tu a tout a fait raison !

  11. #11
    Membre émérite Avatar de ctxnop
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2007
    Messages
    858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Morbihan (Bretagne)

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

    Informations forums :
    Inscription : Juillet 2007
    Messages : 858
    Par défaut
    Oui, ça ou autre chose, peut importe, a mon avis il veut les forms déclarés dans ses assemblies à lui, pas autre chose.
    Tester la présence dans le GAC va éviter tout le framework .net, donc c'est déjà pas mal. Mais il peut aussi avoir des assembly tierces en copie locale, qu'il faudrait esquiver également.
    Mais clairement, parcourir la totalité des assembly du AppDomain n'est pas une bonne idée ^^'.

  12. #12
    Membre expérimenté
    Profil pro
    Mangeur de gauffre
    Inscrit en
    Octobre 2007
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Mangeur de gauffre

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 413
    Par défaut
    Citation Envoyé par bluedeep
    Par ailleurs, les tests fondés sur un pattern spécifique du nom ne me semblent pas une bonne idée.
    Bien sur !
    C'etait juste un test comme un autre pour le proof of concept de la pertinence de ma boucle

  13. #13
    Membre émérite Avatar de ctxnop
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2007
    Messages
    858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Morbihan (Bretagne)

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

    Informations forums :
    Inscription : Juillet 2007
    Messages : 858
    Par défaut
    Citation Envoyé par olibara Voir le message
    Pour le createInstance je ne suis pas certain que ce soit nécessaire
    mais comme l'intention in fine est de browser tous les controls de la form il me semblait que l'intanciation est nécessaire
    Tout dépend de comment tu vois la chose.
    S'il s'agit de formulaires conçus uniquement via le concepteur de WinForm de Visual Studio, à chaque contrôle correspond un membre (souvent privé, ou internal pour le VB, mais cela peut être modifié dans le concepteur et donc tu peux avoir des membres publiques ou protégés également).
    Du coup, par reflexion, tu peux continuer le même processus, tu énumères tous les membres et tu recherche ceux qui héritent de Control.

    Attention cependant, tout contrôle ajouté au runtime, par code utilisateur, ne sera pas détecté.
    Cependant si tu parcours les contrôles d'une instance tu dois le faire récursivement et tu va trouver beaucoup plus de contrôle que ceux qui ont été posés. Par exemple, quand tu pose une grille, le seul contrôle posé est la grille, mais cette grille utilise en interne des choses comme des scrollbars, des labels, des textboxs, etc...

    Pas de bonne solution donc, mais le parcourt par reflexion est à mon avis plus ce que tu recherche.

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

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Par défaut
    Citation Envoyé par ctxnop Voir le message
    Mais clairement, parcourir la totalité des assembly du AppDomain n'est pas une bonne idée ^^'.
    Je ne suis pas entiérement d'accord avec toi : après, tout dépend du niveau d'organisation ou de désorganisation de sa solution. Si tout est nommé proprement et les attributs des assemblies positionnés clairement, il est très facile d'élaguer en testant par exemple l'attribut AssemblyProduct, dont on peut penser qu'il porte le nom de son application pour ses assemblies "home made".

  15. #15
    Membre émérite Avatar de ctxnop
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2007
    Messages
    858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Morbihan (Bretagne)

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

    Informations forums :
    Inscription : Juillet 2007
    Messages : 858
    Par défaut
    Citation Envoyé par Bluedeep Voir le message
    Je ne suis pas entiérement d'accord avec toi : après, tout dépend du niveau d'organisation ou de désorganisation de sa solution. Si tout est nommé proprement et les attributs des assemblies positionnés clairement, il est très facile d'élaguer en testant par exemple l'attribut AssemblyProduct, dont on peut penser qu'il porte le nom de son application pour ses assemblies "home made".
    Bah oui mais du coup tu ne parcours pas l'intégralité des assembly du AppDomain, donc au final tu dis la même chose que moi
    Je me suis peut être mal exprimé, je ne voulais pas dire qu'il ne fallait pas utiliser "AppDomain.CurrentDomain.GetAssemblies()". On peut tout à fait l'utiliser pour la première boucle. Par contre, ce que j'entendais "parcourir" toutes les assembly du AppDomain, c'est de faire un GetType() sur chacune des assembly du AppDomain et tester chaque type retourné pour vérifier si c'est une Form.

  16. #16
    Membre expérimenté
    Profil pro
    Mangeur de gauffre
    Inscrit en
    Octobre 2007
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Mangeur de gauffre

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 413
    Par défaut
    Salut

    Merci pour cet intéressant débat technique plein d'enseignement

    Je vais me battre pratiquement avec cela ce soir

    L'intention comme je l'avais dis est d'avoir un petit module que je pourrais greffer facilement dans une application pour extraire automatiquement tous les text de control susceptible d'etre traduits !

    Dommage d'ailleurs que VS ne propose pas cela !!

  17. #17
    Membre émérite Avatar de ctxnop
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2007
    Messages
    858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Morbihan (Bretagne)

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

    Informations forums :
    Inscription : Juillet 2007
    Messages : 858
    Par défaut
    Si c'est pour faire de la traduction, une extension Visual Studio est plus adaptée. D'autant que les extension en question ne se limiteront pas aux contrôles des formulaires, ils trouveront également tous les textes comme ceux des messagebox, ce qui est écrit dans les fichiers de logs, etc...
    Je pense notamment à Resharper qui fait ça.
    Dans tout les cas ça reste un gros boulot, bon courage ^^'.

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

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Par défaut
    Citation Envoyé par ctxnop Voir le message
    Bah oui mais du coup tu ne parcours pas l'intégralité des assembly du AppDomain, donc au final tu dis la même chose que moi
    Je me suis peut être mal exprimé, je ne voulais pas dire qu'il ne fallait pas utiliser "AppDomain.CurrentDomain.GetAssemblies()". On peut tout à fait l'utiliser pour la première boucle. Par contre, ce que j'entendais "parcourir" toutes les assembly du AppDomain, c'est de faire un GetType() sur chacune des assembly du AppDomain et tester chaque type retourné pour vérifier si c'est une Form.
    Ok, donc ajouter un test du style :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if(assembly.GlobalAssemblyCache == false &&
                        ((AssemblyProductAttribute)(assembly.GetCustomAttributes(typeof(AssemblyProductAttribute), true).First())).Product == "MyProduct")
    On est d'accord ?

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

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Par défaut
    Citation Envoyé par olibara Voir le message
    Dommage d'ailleurs que VS ne propose pas cela !!
    Peut être, parce que, en général, si le support multilingue est nécessaire, il devient un pré-requis au moment du design et on conçoit l'application pour cela en utilisant des fichiers de resources.

    Il est assez rare de le faire a posteriori.

  20. #20
    Membre expérimenté
    Profil pro
    Mangeur de gauffre
    Inscrit en
    Octobre 2007
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Mangeur de gauffre

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 413
    Par défaut
    Citation Envoyé par bluedeep
    Peut être, parce que, en général, si le support multilingue est nécessaire, il devient un pré-requis au moment du design et on conçoit l'application pour cela en utilisant des fichiers de resources.

    Il est assez rare de le faire a posteriori.
    Il peut arriver de decider a posteriori qu'une APP doit etre traduite
    Et meme en preparant des resx localisé a priori il est facille d'oublier certaines traductions

    Dont pouvoir generer autamatiquement une listre structurée des text est une aide précieuse !

    Et idealement il faudrait un Browser de control et un parseur de Resx (qui lui peut se faire mon avis sur le texte source)

Discussions similaires

  1. Sub valable pour toutes les forms d'une application
    Par serana71 dans le forum VB 6 et antérieur
    Réponses: 3
    Dernier message: 27/05/2010, 15h49
  2. Réponses: 7
    Dernier message: 26/05/2008, 11h33
  3. Lister toutes les forms d'une application
    Par Aspic dans le forum Windows Forms
    Réponses: 15
    Dernier message: 01/12/2007, 21h22
  4. parcourir les forms et les objets d'une applications
    Par aadelfa dans le forum C++Builder
    Réponses: 32
    Dernier message: 21/12/2006, 13h54
  5. Réponses: 7
    Dernier message: 27/10/2005, 14h24

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