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:
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:
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 :
http://img458.imageshack.us/img458/7749/treeviewzc2.jpg
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:
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... 8O
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 :mrgreen: !
:roll: c'est clair ce que je dis ou bien 8O ?
j'espère que l'un ou l'une de vous saura me renseigner !
ciao!
Etienne.