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

ASP.NET Discussion :

Ajout dynamique de treeviews/eventHandler


Sujet :

ASP.NET

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Juin 2006
    Messages
    40
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 40
    Par défaut Ajout dynamique de treeviews/eventHandler
    Bonjour messieurs/dames !

    [DISCLAIMER]
    je suis un utilisateur nouveau du C# alors soyez indulgents svp !
    [/DISCLAIMER]


    Après avoir recherché quelques heures (si si, je vous assure), je me décide a poster un sujet parceque je ne m'en sors pas de ce problème !!!

    Allons zy !

    Alors c'est assez simple:
    Je voudrais afficher dans la partie gauche un treeview issu d'un fichier XML construit de la facon suivante :
    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
     
    <?xml version="1.0" encoding="utf-8" ?>
    <Root val="MyTreeView">
      <Chapter val="chapter1">
        <Num val="1"></Num>
        <Page val="4"></Page>
        <Description val="chapter1 description"></Description>
        <SubChapter val="subChapter1">
          <Num val="1"></Num>
          <Page val="5"></Page>
          <Description val="subChapter1 description"></Description>
          <SubSubChapter val="subSubChapter1">
            <Num val="1"></Num>
            <Page val="6"></Page>
            <Description val="subSubChapter1 description"></Description>
          </SubSubChapter>
          <SubSubChapter val="subSubChapter2">
            <Num val="2"></Num>
            <Page val="7"></Page>
            <Description val="subSubChapter2 description"></Description>
          </SubSubChapter>
        </SubChapter>
        <SubChapter val="subChapter2">
          <Num val="2"></Num>
          <Page val="8"></Page>
          <Description val="subChapter2 description"></Description>
        </SubChapter>
      </Chapter>
      <Chapter val="chapter2">
        <Num val="2"></Num>
        <Page val="9"></Page>
        <Description val="chapter2 description"></Description>
      </Chapter>
    </Root>
    Ensuite, lors d'un click sur un noeud de l'arbre, je veux mettre à jour une table placée dans la partie gauche de la page avec les informations contenue dans le noeud sélectionné selon le code C# suivant :

    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
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
     
    protected void treeview_SelectNodeChanged(Object sender, EventArgs e)
        {
            System.Web.UI.WebControls.TreeView origin = (System.Web.UI.WebControls.TreeView)sender;
     
            //si le noeud déclenchant l'évènement n'a pas de fils
            if (origin.SelectedNode.ChildNodes.Count == 0)
            {
                //on met à jour le label titre avec le text du noeud parent
                titre.Text = origin.SelectedNode.Parent.Value;
                //on récupère les noeuds qui sont au même niveau que celui sélectionnés
                foreach (System.Web.UI.WebControls.TreeNode current in origin.SelectedNode.Parent.ChildNodes)
                {
                    TableCell cl1 = new TableCell();
     
                    //si le noeud courant n'a pas de fils
                    if (current.ChildNodes.Count == 0)
                    {
                        //on rempli la cellule avec le texte du noeud courant
                        cl1.Text = current.Text;
                    }
                    else
                    {
                        //sinon on créé un nouveau treeview et on lui ajoute un clone du noeud courant
                        System.Web.UI.WebControls.TreeView tv = new System.Web.UI.WebControls.TreeView();
                        tv.Nodes.Add((System.Web.UI.WebControls.TreeNode)Cloner.CloneTreeNode(current));
                        //on lui associe un event auquel on lie la fonction
                        tv.SelectedNodeChanged += new EventHandler(treeview_SelectNodeChanged);
                        //on le met dans la cellule
                        cl1.Controls.Add(tv);
                    }
     
                    //on créé ensuite un textBox éditable contenant la valeur du noeud courant
                    System.Web.UI.WebControls.TextBox edit = new System.Web.UI.WebControls.TextBox();
                    edit.Text = current.Value;
                    //on l'ajoute à la cellule
                    TableCell cl2 = new TableCell();
                    cl2.Controls.Add(edit);
     
                    //on ajoute les cellules à une ligne
                    TableRow tr = new TableRow();
                    tr.Cells.Add(cl1);
                    tr.Cells.Add(cl2);
     
                    //on ajoute la ligne dans la table
                    valeurs.Rows.Add(tr);
                }
            }
            else
            {
                //on met à jour le label titre avec le text du noeud sélectionné
                titre.Text = origin.SelectedNode.Text;
     
                //on récupère les noeuds fils du noeud sélectionné
                foreach (System.Web.UI.WebControls.TreeNode current in origin.SelectedNode.ChildNodes)
                {
                    TableCell cl1 = new TableCell();
     
                    //si le noeud courant n'a pas de fils
                    if (current.ChildNodes.Count == 0)
                    {
                        //on rempli la cellule avec le texte du noeud courant
                        cl1.Text = current.Text;
                    }
                    else
                    {
                        //sinon on créé un nouveau treeview et on lui ajoute un clone du noeud courant
                        System.Web.UI.WebControls.TreeView tv = new System.Web.UI.WebControls.TreeView();
                        tv.Nodes.Add((System.Web.UI.WebControls.TreeNode)Cloner.CloneTreeNode(current));
                        //on lui associe un event auquel on lie la fonction
                        tv.SelectedNodeChanged += new EventHandler(treeview_SelectNodeChanged);
                        //on le met dans la cellule
                        cl1.Controls.Add(tv);
                    }
     
                    //on créé ensuite un textBox éditable contenant la valeur du noeud courant
                    System.Web.UI.WebControls.TextBox edit = new System.Web.UI.WebControls.TextBox();
                    edit.Text = current.Value;
                    //on l'ajoute à la cellule
                    TableCell cl2 = new TableCell();
                    cl2.Controls.Add(edit);
     
                    //on ajoute les cellules à une ligne
                    TableRow tr = new TableRow();
                    tr.Cells.Add(cl1);
                    tr.Cells.Add(cl2);
     
                    //on ajoute la ligne dans la table
                    valeurs.Rows.Add(tr);
                }
            }
            origin.SelectedNode.Selected = false;
        }
    une image valant bien des mots, voici ce que j'obtient :


    Je n'ai donc pas de problèmes pour faire ceci, mais mon problème se situe au niveau de ce morceau de code :
    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
     
    //si le noeud courant n'a pas de fils
                    if (current.ChildNodes.Count == 0)
                    {
                        //on rempli la cellule avec le texte du noeud courant
                        cl1.Text = current.Text;
                    }
                    else
                    {
                        //sinon on créé un nouveau treeview et on lui ajoute un clone du noeud courant
                        System.Web.UI.WebControls.TreeView tv = new System.Web.UI.WebControls.TreeView();
                        tv.Nodes.Add((System.Web.UI.WebControls.TreeNode)Cloner.CloneTreeNode(current));
                        //on lui associe un event auquel on lie la fonction
                        tv.SelectedNodeChanged += new EventHandler(treeview_SelectNodeChanged);
                        //on le met dans la cellule
                        cl1.Controls.Add(tv);
                    }
    donc pour les explications, lorsque le noeud a afficher dans la table possèdent des fils qui ne sont pas des feuilles, j'ajoute un treeview dans la cellule correspondante en ajoutant a sa collection de noeud un clone du noeud en question (entre parenthèses, j'ai été surpris de voir qu'il n'y avait pas de méthode clone (je ne parle pas de memberviseclone) implémenté dans les objets C#, si ca vous interesse d'avoir un cloner de treenode, tell me !)

    Ensuite je veux ajouter un event (c'est le même que pour le treeview parent) au treeview nouvelement créé ! Le problème c'est que quand je click sur mon nouveau treeview, aucun event n'est lancé...ou plutôt si, juste celui de reload de la page

    Alors pour vous prouver que j'ai recherché, j'ai mis la main sur un exemple ou l'on disait qu'il fallait utiliser le ViewState pour créer l'objet dans le pageload afin de l'ajouter dans l'arborescence des controles de la page...
    j'ai bien compris l'idée, seulement l'exemple donné concernait un seul objet a créer dans la page alors que dans mon cas j'ai plusieurs objets a créer dynamiquement (je n'en connais pas le nombre à l'avance et ils n'ont pas d'ID puisque j'utilise une variable locale de création "tv") dans des cellules de lignes d'une table...

    je pense pouvoir contourner le problème en utilisant une variable globale de collection de treeview que je mettrai a jour et que je créérai dans le pageload en fonction du ViewState... mais ca me parait bizarre d'avoir a faire quelque chose d'aussi compliqué dans un langage objet ! et en plus c'est moche !

    c'est clair ce que je dis ou bien ?

    j'espère que l'un ou l'une de vous saura me renseigner !

    ciao!

    Etienne.

  2. #2
    Membre Expert Avatar de Arthis
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    1 265
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : Italie

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 265
    Par défaut
    Je crains, eut égard à mes faibles compétences en C#, que ce ne soit moche... Je ne vois pas trop d'autres solutions sur le moment...

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

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 011
    Par défaut
    Ah, l'éternel problème des contrôles créés dynamiquement.
    Regarde un peu dans le forum, tu trouveras la solution.

  4. #4
    Membre averti
    Inscrit en
    Juin 2006
    Messages
    40
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 40
    Par défaut
    Citation Envoyé par guitoux1
    Ah, l'éternel problème des contrôles créés dynamiquement.
    Regarde un peu dans le forum, tu trouveras la solution.
    moui...j'ai déjà vu pas mal de tomics relatif a cela mais j'ai bien du mal à les relier à mon problème... et les solutions me paraissent souvent lourdes...
    menfin, je vais continuer a chercher ! merci !

  5. #5
    Membre averti
    Inscrit en
    Juin 2006
    Messages
    40
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 40
    Par défaut
    Hola ! c'est rapide !

    euh, ben ouais, c'est une solution qui doit fonctionner mais bon c'est quand même bien bourrin quoi...

    le c# cay le mal...

    d'autres idées ??

  6. #6
    Membre Expert Avatar de Arthis
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    1 265
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : Italie

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 265
    Par défaut
    regarde la réponse de Sphax

    http://www.developpez.net/forums/sho...=362667&page=2

    cela devrait te donner des idées pour retrouver tes petits.. enfin j'espere, c'est que je m'y perds un peu moi dans tous ces trucs a la fin

  7. #7
    Membre averti
    Inscrit en
    Juin 2006
    Messages
    40
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 40
    Par défaut
    Citation Envoyé par Sphax
    Pour conserver les valeurs des controles dynamiques il n'y a rien à faire sinon penser à les recréer au bon moment lors du postback. Tu peux par exemple le faire dans une surcharge de CreateChildControl de la page. Surtout ne pas réinventer le viewstate ce serait dommage .

    Voici le code d'une page qui contient un bouton et un placeholder, qd on clique sur le bouton j'ajoute une textbox au placeholder. Les valeurs des textbox sont bien conservées d'un postback à l'autre. La seule chose conservée explicitement dans le viewstate est le nombre de textbox à créer :

    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
     
    private int TotalDynamicControls
    		{
    			get
    			{
    				if (ViewState["TotalDynamicControls"] == null)
    				{
    					return 0;
    				}
     
    				return (int)ViewState["TotalDynamicControls"];
    			}
     
    			set
    			{
    				ViewState["TotalDynamicControls"] = value;
    			}
    		}
     
    		protected override void CreateChildControls()
    		{
    			base.CreateChildControls();
     
    			for (int i = 0; i < TotalDynamicControls; ++i)
    			{
    				TextBox tmp = new TextBox();
    				phHolder.Controls.Add(tmp); //phHolder c'est mon placeHolder
    			}
    		}
     
    		protected void Button1_Click(object sender, EventArgs e)
    		{
    			TextBox tmp = new TextBox();
    			phHolder.Controls.Add(tmp);
    			TotalDynamicControls++;
    		}

    voilà la réponse de sphax au problème. C'est bien ce que j'avis compris, mais le problème c'est que je ne sais pas comment récupérer les infos de mon treeview parent...parceque ce n'est pas qu'un text, c'est une collection de noeuds qui eux mêmes ont potentiellement une collection de fils...et ainsi de suite !


    EDIT:je vais quand même tester ca, même si j'arrive pas a comprendre comment il arrive a récupérer les infos des controles...

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

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 011
    Par défaut
    Tu peux stocker dans le ViewState la référence à "current" (noeud actuellement sélectionné). Puis dans la méthode CreateChildControl, ben tu remet le code de Clonage de treeView. Tu sauras quel TV cloner car tu auras la référence dans le viewstate

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

Discussions similaires

  1. [VBA] Ajouter dynamiquement une référence
    Par jpharand dans le forum VBA Access
    Réponses: 23
    Dernier message: 16/04/2010, 23h28
  2. Ajout dynamique de colonne identity
    Par graphicsxp dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 16/11/2005, 16h40
  3. ajouter dynamiquement des items dans un popup menu
    Par Malone dans le forum Composants VCL
    Réponses: 7
    Dernier message: 23/08/2005, 16h08
  4. Réponses: 2
    Dernier message: 10/05/2005, 15h54
  5. Ajout dynamique d'un contrôle à une fenêtre
    Par Yacine95000 dans le forum MFC
    Réponses: 6
    Dernier message: 08/06/2004, 16h03

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