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.
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 );
}
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
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" );
}
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é...

"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 un
Code : Sélectionner tout - Visualiser dans une fenêtre à part
root.DropDownItems.CopyTo( unArrayFixCommeCaPasDeProbleme, 0);
suivit d'un
Code : Sélectionner tout - Visualiser dans une fenêtre à part
menuStrip.Items.AddRange(unArrayFixCommeCaPasDeProbleme);
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

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?