AddHandler avec Handler qui prend ses arguments lors d'une boucle

Résolu
Pulcrix - 12 sept. 2012 à 10:28
 Pulcrix - 12 sept. 2012 à 16:46
Bonjour à tous,

Je suis débutant en VB.NET et je rencontre actuellement un problème lors de l'attribution d'EventHandlers à des contrôles crées dynamiquement.
En résumé à chaque création d'une nouvelle DropDownItem dans le menu de mon application, je veux lui attribuer l'exécution d'une Sub qui prend des arguments dépendant de la DropDownItem cliquée.
Par exemple si je clique sur "Calculateur n°1", une fenêtre aux caractéristiques du calculateur n°1 doit être crée pas la Sub. Ainsi de suite avec "Calculateur n°2" etc...

Voici le bout code en question:
For i As Integer = 0 To NumberOfECU - 1
Dim j As Integer
    	j = i

    	TCFMonitoringTool.CalculateursToolStripMenuItem.DropDownItems.Add(menuArray(i, 2)) 'Création dynamique du menu des Calculateurs
    	AddHandler TCFMonitoringTool.CalculateursToolStripMenuItem.DropDownItems.Item(i).Click, Sub(senderObj, args) _
                beforeCreateECU(TCFMonitoringTool.CalculateursToolStripMenuItem.DropDownItems.Item(j), j)

Next


Sub beforeCreateECU(ByVal menuItem As ToolStripItem, ByVal ECUline As Integer)

     	Dim i As Integer = 0
     	Dim ECUCreated As Boolean = False

     	While ECUCreated = False

         	If IsNothing(ECU(ECUline, i)) False AndAlso ECU(ECUline, i).Text "" Then
           
             		createECU(ECUline, i, menuItem)
             		ECUCreated = True
            
         	ElseIf IsNothing(ECU(ECUline, i)) = True Then

             		createECU(ECUline, i, menuItem)
             		ECUCreated = True
         	Else
             		i = i + 1
         	End If
     	End While

 End Sub


Suite à ceci, j'ai bien les DropDownItems qui apparaissent dans le menu de l'application, avec les nom corrects, mais lorsque je clique par exemple sur celle qui s'appelle "Calculateur n°1", c'est une fenêtre à l'image de "Calculateur n°6" qui apparaît. C'est à dire le dernier calculateur de ma liste, donc la dernière itération de la boucle For.
Pourquoi les arguments envoyés à ma Sub sont systématiquement les mêmes, quel que soit la DropDownItem cliquée? Pourtant dans AddHandler je précise bien que chaque Item(i) doit avoir sa propre Sub(argument1(i), argument2(i)) associée?

Merci d'avance pour votre aide.
A voir également:

5 réponses

J'ai demandé de l'aide et on m'a aiguillé sur cette proposition qui fonctionne je l'affiche ici pour compléter le sujet. Donc maintenant, en cliquant sur le DropDownItem, une fenêtre avec le nom associé à l'item apparaît et possède la bonne mise en forme.
Il s'agit de travailler avec AddressOf (comme NHenry m'a conseillé) et de créer un dictionnaire pour utiliser les propriétés (dont l'index) de l'Item correspondant à senderObj pour pouvoir travailler dans la Sub:

Private _dicoMenuItems As New Collections.Generic.Dictionary(Of ToolStripItem, Integer)

For i As Integer = 0 To NumberOfECU - 1
                      TCFMonitoringTool.CalculateursToolStripMenuItem.DropDownItems.Add(menuArray(i, 2))

AddHandler TCFMonitoringTool.CalculateursToolStripMenuItem.DropDownItems.Item(i).Click, AddressOf beforeCreateECU
                _dicoMenuItems.Add(TCFMonitoringTool.CalculateursToolStripMenuItem.DropDownItems.Item(i), i)

Next

Sub beforeCreateECU(ByVal senderObj As Object, ByVal e As System.EventArgs)

        Dim i As Integer = 0
        Dim ECUCreated As Boolean = False
        Dim ECUline As Integer = _dicoMenuItems(DirectCast(senderObj, ToolStripItem))

        While ECUCreated = False
            If IsNothing(ECU(ECUline, i)) False AndAlso ECU(ECUline, i).Text "" Then
                createECU(ECUline, i, senderObj)
                ECUCreated = True
            ElseIf IsNothing(ECU(ECUline, i)) = True Then
                createECU(ECUline, i, senderObj)
                ECUCreated = True
            Else
                i = i + 1
            End If
        End While
End Sub


Voilà si ca peut aider quelqu'un.
En tout cas merci pour votre aide.
Bonne soirée.
3
NHenry Messages postés 15113 Date d'inscription vendredi 14 mars 2003 Statut Modérateur Dernière intervention 22 avril 2024 159
12 sept. 2012 à 12:24
Bonjour,

Regardes la valeur de SenderObj (premier paramètre de l'évènement), il t'indique qui est l'expéditeur du message.

---------------------------------------------------------------------
[list=ordered][*]Pour poser correctement une question et optimiser vos chances d'obtenir des réponses, pensez à lire le règlement CS, celui-ci pour bien poser votre question ou encore celui-ci pour les PFE et autres exercices.[*]Quand vous postez un code, merci d'utiliser la coloration syntaxique (3ième icône en partant de la droite : ).[*]En VB.NET pensez à activer Option Explicit et Option Strict (propriété du projet) et à retirer l'import automatique de l'espace de nom Microsoft.VisualBasic (onglet Références dans les propriétés du projet).[*]Si votre problème est résolu (et uniquement si c'est le cas), pensez à mettre "Réponse acceptée" sur le ou les messages qui vous ont aidés/list
---
Mon site
0
Merci pour votre réponse NHenry.

Je suis passé en mode Débogage avec point d'arrêt sur la ligne du AddHandler, mais je n'arrive pas à mettre un espion sur senderObj ou même à voir sa valeur à l'instant t. C'est d'ailleurs ce qui me pose aussi problème avec ce AddHandler: il m'est impossible d'analyser quoi que ce soit à part les valeurs de i et j.
0
NHenry Messages postés 15113 Date d'inscription vendredi 14 mars 2003 Statut Modérateur Dernière intervention 22 avril 2024 159
12 sept. 2012 à 13:52
Bonjour,

Pourquoi ne pas utiliser un Delegate pour appeler une autre Sub, car les Lambdas, c'est bien, mais quand on debug, c'est pas évident.

AddHandler ..., New EventDelegate(AdressOf MaSub)

Remplacer les textes en rouge par la bonne valeur.

---------------------------------------------------------------------
[list=ordered][*]Pour poser correctement une question et optimiser vos chances d'obtenir des réponses, pensez à lire le règlement CS, celui-ci pour bien poser votre question ou encore celui-ci pour les PFE et autres exercices.[*]Quand vous postez un code, merci d'utiliser la coloration syntaxique (3ième icône en partant de la droite : ).[*]En VB.NET pensez à activer Option Explicit et Option Strict (propriété du projet) et à retirer l'import automatique de l'espace de nom Microsoft.VisualBasic (onglet Références dans les propriétés du projet).[*]Si votre problème est résolu (et uniquement si c'est le cas), pensez à mettre "Réponse acceptée" sur le ou les messages qui vous ont aidés/list
---
Mon site
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Désolé je ne suis pas très doué je ne parviens pas à faire fonctionner votre exemple. Ma sub n'est apparemment pas compatible avec le Delegate.
Cependant j'ai observé ce qui se passe en mettant un point d'arrêt devant ma Sub et à chaque fois menuItem et ECULine correspondent aux dernières valeurs de la boucle de la fonction précédente.
0
Rejoignez-nous