Alors bonjour à tous,
Je suis victime d'un étrange problême. J'utilise les ToolStripMenuItem et ToolStripItemCollection pour générer automatiquement un menu contextuel dynamique en fonction d'un fichier xml.
La génération des ToolStripMenuItem se fait de manière récursive. Mais lorsque je veut rajouter les ToolStrip ainsi obtenu dans le MenuStrip. J'obtient ce problême.
Quel Problême me direz vous?
Eh bien pour être clair voila un peu de code :
Voila la fonction qui est chargé de prendre le fichier XML et de commencer à naviguer dedans.
Et voila la fonction récursive qui rajoute le noeud XML (transformer en ToolStripMenuItem) au parent (un autre ToolStripMenuItem)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 internal void LoadMenuFromXml ( XmlDocument xml ) { ToolStripMenuItem root = new ToolStripMenuItem( "root" ); foreach (XmlNode node in xml.LastChild.ChildNodes) this.Node2ToolStripMenu( node, ref root ); this._strip.Items.AddRange( root.DropDownItems ); }
Donc lorsque j'ai finit avec tous les noeuds enfant, il faut rajouter tous les menus du premier niveau (au niveau 0, il n'y a q'un seul menu et c'est 'root' mais lui on le veut pas dans le ContextMenu) au MenuStrip. Mais lors de l'utilisation de la fonction AddRange, l'exception 'ArgumentOutOfRangeException' est lancé...
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 internal void Node2ToolStripMenu ( XmlNode node, ref ToolStripMenuItem parent ) { if ( node.HasChildNodes ) if ( node.Attributes["text"] != null ) { ToolStripMenuItem actualMenu; actualMenu = node.Attributes["icon"] != null ? new ToolStripMenuItem( node.Attributes["text"].Value, new Icon( node.Attributes["icon"].Value ).ToBitmap() ) : new ToolStripMenuItem( node.Attributes["text"].Value ); parent.DropDownItems.Add( actualMenu ); foreach ( XmlNode child in node.ChildNodes ) Node2ToolStripMenu( child, ref actualMenu ); } else throw new Exception( "The attributes 'text' can't be missing" ); else if ( node.Attributes["text"] != null ) if ( node.Attributes["icon"] != null ) parent.DropDownItems.Add( new ToolStripMenuItem( node.Attributes["text"].Value, new Icon( node.Attributes["icon"].Value ).ToBitmap() ) ); else parent.DropDownItems.Add( new ToolStripMenuItem( node.Attributes["text"].Value ) ); else throw new Exception( "The attributes 'text' can't be missing" ); }
"Mais c'est une collection" me direz vous. Et bien en fait, comme le AddRange ne va faire que une boucle sur le contenu de la collection, à chaque tour de cette boucle, le ToolStripMenuItem concerné est enlevé de root.DropDownItems (j'utilise VisualStudio 2008 et le Count de cette collection passe de 10 à 9 à ... à 1).
Sauf que comme d'un coup il veut appeler le 6ème menu et que du coup il n'y en a plus que 5, bam OutOfRange.
J'ai déjà trouver la parrade à cet étrange problême mais comme dit je suis assez curieux et j'aurais voulu savoir pourquoi ce problême?
Cordialement,
Inarius
PS: la solution est toute bête, il faut faire unsuivit d'un
Code : Sélectionner tout - Visualiser dans une fenêtre à part root.DropDownItems.CopyTo( unArrayFixCommeCaPasDeProbleme, 0);PS2: Pour ceux que le code intéresse, je le proposerait bientôt pour faire partit du Framework DVP.NET. Mais d'abord ajout des évennements et encore d'autres choses
Code : Sélectionner tout - Visualiser dans une fenêtre à part menuStrip.Items.AddRange(unArrayFixCommeCaPasDeProbleme);
EDIT:
PS3: Une petite question pour les bons (moi encore étudier) les ref sont nécessaires ou pas? Je les avait mis pour voir si c'était ca le probleme mais comme dit je sais pas trop... donc ref ou pas ref?
Partager