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 :

[C# 2.0] Comment invoquer un objet à partir d'une chaîne de caractères ?


Sujet :

C#

  1. #1
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 764
    Points : 2 705
    Points
    2 705
    Par défaut [C# 2.0] Comment invoquer un objet à partir d'une chaîne de caractères ?
    Hello,

    J'ai une méthode à laquelle j'envoie en paramètre un nom de composant (sous forme de chaîne, extraite d'une base de données).

    Mais comment utiliser cette chaîne dans l'expression d'accès d'une propriété à ce composant, afin de pouvoir agir dessus ?

    Exemple :
    Soit param une chaîne contenant "Label1"

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    void changerNom(string param)
    {
        this.param.Text = "bidule";
    }
    Je voudrais en queslque sorte avoir une méthode qui fait l'inverse de Component.ToString...

    Merci.

  2. #2
    Rédacteur
    Avatar de Thomas Lebrun
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    9 161
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Points : 19 434
    Points
    19 434
    Par défaut
    J'ai rien compris.....

  3. #3
    Membre éprouvé Avatar de guitoux1
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 011
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 011
    Points : 1 256
    Points
    1 256
    Par défaut
    Je crois comprendre (mais c'est vrai que t'es pas clair là) que tu veux parler de Reflexion.

    Va voir là ! http://www.developpez.net/forums/sho...d.php?t=166458

  4. #4
    Membre habitué
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    105
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Novembre 2003
    Messages : 105
    Points : 134
    Points
    134
    Par défaut
    Tu peux aussi éventuellement itérer à travers la collection de contrôles pour trouver celui dont la propriété Name correspond à ta chaîne de caractères.

    Bonne chance

  5. #5
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 764
    Points : 2 705
    Points
    2 705
    Par défaut
    Morpheus :
    J'ai reformulé la question

    Guitoux1 :
    Je n'ai jamais utilisé la réflexion auparavant. J'ai été voir dans mon bouquin d'O'Reilly, mais je ne vois pas le rapport. Ca parle d'assemblage... Dans le fil du lien que tu m'as donné, le besoin est différent. Le gars veut créer des composants. Moi, je veux simplement en changer une propriété.

    Smikar :
    J'y ai pensé, mais ça m'obligerait à parcourir de manière récursive les contrôles. Un peu lourdingue, surtout que je dispose déjà des noms des contrôles.

  6. #6
    Membre éprouvé Avatar de guitoux1
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 011
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 011
    Points : 1 256
    Points
    1 256
    Par défaut
    oui mais avant de changer de changer la propriété d'un composant, il faut bien le créer, non ? Or là tu pars d'une chaine de caractère, donc pas d'un composant créé

  7. #7
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 764
    Points : 2 705
    Points
    2 705
    Par défaut
    Le composant existe déjà.
    J'ai tout disposé dans Visual. Ensuite, selon la langue, je change le texte des libellés, le contenu des listes déroulantes, etc.

  8. #8
    Expert éminent
    Avatar de neguib
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    3 627
    Détails du profil
    Informations personnelles :
    Âge : 64
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 627
    Points : 7 879
    Points
    7 879
    Par défaut
    Citation Envoyé par oodini
    Morpheus :
    J'ai reformulé la question.
    Oui et j'ai donc reformulé ton titre
    Citation Envoyé par oodini
    Guitoux1 :
    Je n'ai jamais utilisé la réflexion auparavant. J'ai été voir dans mon bouquin d'O'Reilly, mais je ne vois pas le rapport. Ca parle d'assemblage... Dans le fil du lien que tu m'as donné, le besoin est différent. Le gars veut créer des composants. MOi, je veux simplement en changer une propriété.
    Tu te trompe car Guitoux a très bien répondu en t'indiquant la piste de Reflection. Cet outil est très puissant et répond parfaitement à ton souci. Il te faut simplement comprendre que les composants auquels tu veux acceder sont en fait des champs(Field) généralement Private. Ce qui necessite l'utilisation de la méthode GetField avec l'énumeration BindingFlags

  9. #9
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 764
    Points : 2 705
    Points
    2 705
    Par défaut
    Citation Envoyé par neguib
    Oui et j'ai donc reformulé ton titre
    Mais mais mais... tu me dépossèdes de ma question. :-)

    Merci de votre diligence, ce problème me bloquait.
    Je vais étudier ça tout de suite, et vous tiens au courant.

    Bon, ce n'est pas très clair pour moi, même après voir lu ton lien (que je te remercie néanmoins de m'avoir fourni).

    Je continue...

    Neguib, je n'y arrive pas...

    Dans l'exemple fourni sur la page du lien que tu as donnée, les manips sont faites en dehors de la classe en question (à partir du Main).

    Reprenons l'exemple donné :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    MyFieldClassA myFieldObjectA = new MyFieldClassA();
    Type myTypeA = Type.GetType("MyFieldClassA");
    FieldInfo myFieldInfo = myTypeA.GetField("field");
    Console.WriteLine("The value of the field is : {0} ", myFieldInfo.GetValue
    (myFieldObjectA));
    La classe (partielle, en 2 morceaux) qui contient les contrôles dont je connais le nom est le formulaire principal. L'endroit où je veux faire la manip est dans une méthode à l'intérieur de la classe considérée.

    La première ligne serait à éliminer, this pouvant prendre la place de myFieldObjectA.

    Pour la seconde, si on garde le nom de classe par défaut du formulaire principal, cela nous donne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Type myTypeA = Type.GetType("Form1");
    Mais ça me renvoie un null...

    La troisième serait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    FieldInfo nomControle= myTypeA.GetField("Label1");
    dans le cas où on aurait un label dans le formulaire.

    La quatrième serait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Control pouet = nomControle.GetValue(this);
    Mais bon... Tout se bloque à cause de la seconde ligne (renvoyant un null).

  10. #10
    Expert éminent
    Avatar de neguib
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    3 627
    Détails du profil
    Informations personnelles :
    Âge : 64
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 627
    Points : 7 879
    Points
    7 879
    Par défaut
    Bon reprenons, si tu veux bien je te propose un petit exercice d'entraînement.
    Crée un nouveau projet test Applications Windows
    Sur ta Form ajoute un contrôle Button (bGetFields) et génère sa méthode click puis ajoute aussi un ListBox (lBGetFields).
    Dans ton code, voilà ce que tu devras avoir:
    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
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Reflection;
    using System.Text;
    using System.Windows.Forms;
    
    namespace CSharpTestsWin
    {
      public partial class MainForm : Form
      {
         public MainForm()
         { InitializeComponent();}
     
         private void bGetFields_Click(object sender, EventArgs e)
         { this.GetMyFields();}
     
    
         private void GetMyFields()
         {
            // recupérer le type de mon objet Form en cours
           Type t = this.GetType();
     
           // créer un bindingFlags pour une recherche sur
           // les objets instanciés et non publics
           BindingFlags bf = BindingFlags.Instance | BindingFlags.NonPublic;
     
           // récupérer les champs correspondant dans this
           FieldInfo[] fi = t.GetFields(bf);
     
           //afficher les champs récupérés        
            this.lBGetFields.Items.Clear();
            foreach( FieldInfo f in fi)
            {this.lBGetFields.Items.Add(f);}
         }
      }
    }
    
    Voilà génère et execute, normalement l'appui sur le bouton devrait lister au moins tous les contrôles de ta Form en cours.
    Si pour cette étape tu piges, essayes ensuite d'avancer vers ton souci, sinon nous passerons à un exercice plus proche de ton cas particulier

  11. #11
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 764
    Points : 2 705
    Points
    2 705
    Par défaut
    Je comprend, quoique je me demande d'où vient, dans la liste, le System.Drawing.Point scrollPosition.

    J'essaye de voir ce que je peux faire de ce prog pour m'aider à avancer dans mon problème. :-)

    Pour l'instant, j'arrive à avoir la liste de tous mes contrôles...

    Je ne comprend pas... Je n'arrive pas à articuler ces méthode getField/GetFields pour que je puisse avoir au final une référence vers un composant.

  12. #12
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 764
    Points : 2 705
    Points
    2 705
    Par défaut
    Euh.. Après une heure de tripatouillage, pourrais-je avoir un nouveau coup de pouce, STP ? :-)

  13. #13
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2006
    Messages
    51
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 51
    Points : 38
    Points
    38
    Par défaut Une Alternative ! ?
    Bonjour,

    Peut etre que tu pourrais contourner le probleme ?
    Si cela t'es possible, au chargement de ta forme tu boucle sur tes controls et les ranges dans une SortedList avec comme clé le nom de tes controls!
    Une fois cela fait tu n'à plus qu'a rappeler tes controls soit par l'index soit par la clé !

    En VB.NET
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    Dim Liste as new SortedList
    for each c as control in MaForme
          Liste.Add(c.Name,c)
    next
    Puis pour l'utilisation
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Dim UnLabel as Label
    Label = liste("LeNomDuLabel")
    En esperant t'avoir aider
    Dis nous si cela te convient
    Bon Courage !

  14. #14
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 764
    Points : 2 705
    Points
    2 705
    Par défaut
    Je dois avouer que cette solution à laquelle j'avais songé devrait marcher, mais elle est également peu élégante.

    Je trouve ça dingue d'en arriver là pour faire un besoin si simple.

    Mais j'apprécie néanmoins ta suggestion.

  15. #15
    Expert éminent
    Avatar de neguib
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    3 627
    Détails du profil
    Informations personnelles :
    Âge : 64
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 627
    Points : 7 879
    Points
    7 879
    Par défaut
    Citation Envoyé par oodini
    Euh.. Après une heure de tripatouillage, pourrais-je avoir un nouveau coup de pouce, STP ? :-)
    ok mais il va falloir patienter au moins une heure je dois terminer un taf

  16. #16
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 764
    Points : 2 705
    Points
    2 705
    Par défaut
    Je t'attend à 16h30 de pied ferme !! :-)

    Je plaisante. Merci pour tes nombreuses contributions.

    HAHAHA !!!

    L'heure de la victoire a sonné !!!

    Je passe finalement par un Type.InvokeMethod :

    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
    try
    {
        Control ContrôleGauche = (Control)this.GetType().InvokeMember(clé,
     BindingFlags.Default | BindingFlags.Public  | BindingFlags.NonPublic |
     BindingFlags.GetField | BindingFlags.Instance, null, this, null);
        Control ContrôleDroit = (Control)this.GetType().InvokeMember
    (compDroit, BindingFlags.Default | BindingFlags.Public |
     BindingFlags.NonPublic | BindingFlags.GetField |
     BindingFlags.Instance, null, this, null);
     
        ContrôleGauche.Size = new System.Drawing.Size((int)g.MeasureString
    (ContrôleGauche.Text, ContrôleGauche.Font).Width, (int)g.MeasureString
    (ContrôleGauche.Text, ContrôleGauche.Font).Height);
        ContrôleGauche.Location = new System.Drawing.Point
    (ContrôleDroit.Location.X - ContrôleGauche.Size.Width - 5,
     ContrôleGauche.Location.Y);
    }
    catch (System.MissingFieldException mme)
    {
        MessageBox.Show = "J'en ai ma claque, j'abandonne !";
    }
    En revanche, je suis un peu paumé avec les BindingsMethods... Si il y en a trop, merci de me le préciser !

  17. #17
    Expert éminent
    Avatar de neguib
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    3 627
    Détails du profil
    Informations personnelles :
    Âge : 64
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 627
    Points : 7 879
    Points
    7 879
    Par défaut
    Bon je te propose tout de même une petite suite, car maintenant nous tentons de récupérer l'objet bouton bGetFields par Reflection donc voici une petite modif du code précédent
    public partial class MainForm : Form
    {
    public MainForm()
    { InitializeComponent();}

    private void bGetFields_Click(object sender, EventArgs e)
    {
    this.GetMyButton();}


    privatevoid GetMyButton()
    {
    // recupérer le type de mon objet Form en cours
    Type t = this.GetType();
    // créer un bindingFlags pour une recherche sur
    // les objets instanciés et non publics
    BindingFlags bf = BindingFlags.Instance | BindingFlags.NonPublic|
    BindingFlags.GetField;
    // récupérer le button bGetFields dans this
    Object monbouton = t.InvokeMember("bGetFields",bf,null,this,null);
    MessageBox.Show(monbouton.ToString());
    }
    }
    Donc ici tu seras très proche d'invoquer la propriété Text de cet objet monbouton pour une modification en "Coucou" par exemple. J'attend ta copie

  18. #18
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 764
    Points : 2 705
    Points
    2 705
    Par défaut
    He, saligaud, tu aurais pu me parler de InvokeMethod() avant ! C'est l'élément qui me manquait ! :-)

  19. #19
    Expert éminent
    Avatar de neguib
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    3 627
    Détails du profil
    Informations personnelles :
    Âge : 64
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 627
    Points : 7 879
    Points
    7 879
    Par défaut
    Citation Envoyé par oodini
    He, saligaud, tu aurais pu me parler de InvokeMethod() avant ! C'est l'élément qui me manquait ! :-)
    Ben tu peux être fier d'avancer quasiment par toi-même, j'ai juste été un poteau indicateur

  20. #20
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 764
    Points : 2 705
    Points
    2 705
    Par défaut
    Citation Envoyé par neguib
    Ben tu peux être fier d'avancer quasiment par toi-même, j'ai juste été un poteau indicateur
    Ouais... Après m'avoir laissé galérer 3 heures...

    En revanche, j'ai un autre souci, inexplicable. Pas moyen de compiler avec l'instruction dans le catch. Ca bloque sur le MessageBox, et ça me dit :

    Erreur 2 Impossible d'assigner à 'Show', car il s'agit d'un 'groupe de méthodes'

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Réponses: 6
    Dernier message: 05/06/2013, 22h57
  2. Réponses: 6
    Dernier message: 27/06/2007, 10h33
  3. importer module à partir d'une chaîne de caractères
    Par j_p_g dans le forum Général Python
    Réponses: 2
    Dernier message: 23/04/2007, 15h15
  4. Réponses: 8
    Dernier message: 16/06/2006, 01h06
  5. Réponses: 6
    Dernier message: 18/01/2006, 16h26

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