|
Site |
Cours VB.net |
|
|
|
Créer des contrôles par code. |
|
|
Dans le code, on peut créer soi-même de toutes pièces, des contrôles et leurs évènements.
Créer par code des contrôles.
Dans le code d'une procédure, il est possible de créer de toute pièce un contrôle, mais attention, il faut tout faire!!
Créons le bouton.
Dim Button1 As New Button
Modifions ses propriétés
Me.Button1.Location = New System.Drawing.Point(56, 144) Me.Button1.Name = "Button1" Me.Button1.Size = New System.Drawing.Size(104, 24) Me.Button1.TabIndex = 0 Me.Button1.Text = "Button1"
Le bouton existe mais il faut l'ajouter à la collection Controls de la fenêtre (Cette collection contient tous les contrôles contenus dans la fenêtre):
Me.Controls.Add(Button1)
Ajouter des évènements.
Le bouton existe mais pour le moment, il ne gère pas les évènements.
Il faut inscrire le bouton dans une méthode de gestion d'évènements. En d'autres termes, Vb doit savoir quelle procédure évènement doit être déclenchée quand un évènement survient. Pour cela, il y a 2 méthodes:
Déclaration dans la partie déclaration du module(en haut) (WithEvents n'est pas accepté dans une procédure):
Private WithEvents Button1 As New Button
Remarque Button1 est accessible dans la totalité du module .
Puis écrire la sub évènement.
Sub OnClique ( sender As Object, EvArg As EventArgs) Handles Button1.Click
End Sub
Ainsi VB sait que pour l'évènement Button1.Click , il faut déclencher la Sub OnClique.
Il semble que quand on fait:Private WithEvents Button1 As Button (sans New) dans la partie déclaration puis DIM Button1 As New Button dans une procédure, la Sub OnClique ne fonctionne pas!!
C'est un problème de 'visibilité' donc bien faire Private WithEvents Button1 As New Button
Remarque: il pourrait y avoir plusieurs Handles sur une même sub, donc des évènements différents sur des objets différents déclenchant la même procédure.
Déclaration (possible dans une procédure):
Dim Button1 As New Button
Puis écrire la gestion de l'évènement.( L'évènement Button1.click doit déclencher la procédure dont l'adresse est BouttonClique)
AddHandler Button1.Click, AddressOf BouttonClique
(ne pas oublier la virgule avant AddressOf)
Enfin on écrit la sub qui 'récupère ' l'évènement:
Private Sub BouttonClique (sender As Object, evArgs As EventArgs)
End Sub
Ainsi VB sait que pour un évènement du Button1 , il faut déclencher la Sub ButtonClique
Exemple avec AddHandler:
Créons un TextBox nommé TB et une procédure déclenchée par KeyUp de ce TextBox:
Dans une procédure (Button1_Click par exemple): Je crée un TextBox nommé TB, je le positionne, je met dedans le texte 'ici une textbox'. Je l'ajoute aux Contrôles du formulaire.
Grâce à 'AddHandler', je lie l'évènement Keyup de cet objet TB à la sub que j'ai crée :TextboxKeyup.
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles
Button1.ClickDim TB As New System.Windows.Forms.TextBox
TB.Location =
New System.Drawing.Point(2, 2)TB.Text = "ici une textBox"
Me.Controls.Add(TB) AddHandler TB.Keyup, AddressOf TextboxKeyup.End sub
Sub TextboxKeyup.(ByVal sender As Object, ByVal e As KeyEventArgs)
...
End Sub
Si je crée un autre bouton TB2, j'ajoute de la même manière AddHandler TB2.Click, AddressOf TextboxKeyup2, ainsi chaque évènement de chaque contrôle à ses propres routines évènement et en cliquant sur le bouton TB2 on déclenche bien TextboxKeyup2
Attention, la procédure TextboxKeyup doit recevoir impérativement les bons paramètres: un objet et un KeyEventArgs car ce sont les paramètres retournés par un KeyUp.
Autre exemple avec AddHandler mais avec 2 boutons:
Il est possible de créer plusieurs contrôles ayant la même procédure évènement:
Exemple: Créons 2 boutons (BT1 et BT2) déclenchant une seule et même procédures (BoutonClique).
Dans ce cas, comment savoir sur quel bouton l'utilisateur à cliqué ?
En tête du module déclarons les boutons (Ils sont public):
Public BT1 As New System.Windows.Forms.Button Public BT2 As New System.Windows.Forms.Button
Indiquons dans form_load par exemple la routine évènement commune (BoutonClique) grâce a AddHandler.
Form_Load
New System.Drawing.Point(2, 2)BT1.Location =
BT1.Text = "Bouton 1"
Me.Controls.Add(BT1)BT2.Location =
New System.Drawing.Point(100, 100)BT2.Text = "Bouton 2"
Me.Controls.Add(BT2) AddHandler BT1.Click, AddressOf BoutonClique AddHandler BT2.Click, AddressOf BoutonCliqueEnd Sub
Si c'est le bouton 1 qui a été cliqué, afficher "button1" dans une TextBox:
Sub
BoutonClique(ByVal sender As Object, ByVal e As EventArgs)If sender Is BT1 Then
TextBox1.Text = "button 1"
ElseIf sender Is BT2 ThenTextBox1.Text = "button 2"
End If End SubLa ruse est que déterminer quel objet (quel bouton) à déclenché l'évènement, pour cela on utilise le premier paramètre, le sender;
If sender Is BT1 Then : Si le sender est le bouton1..
Noter bien:
- le mot clé handles permet d'associer un événement à une procédure au moment de la conception.
Le concepteur sait qu'une procédure doit gérer les événements (il peut y en avoir plusieurs).
- le mot clé addhandler permet d'associer un événement à une procédure au moment de l'exécution.
Ceci est utile dans un cadre producteur-consommateur d'événements. Un objet produit un événement qui doit informer d'autres objets; au cours de l'exécution on crée l'association entre l'évènement et une procédure.
Remarque importante:
Les
Handler ne sont en fait libérés qu’au déchargement complet du programme
(application.exit) et non à la fermeture de la fenêtre et des objets contenus
dans celle-ci...
Il
faut donc utiliser RemoveHandler pour libérer le
Handler. L’instruction
s’utilise de la même façon que le AddHandler ! (reprendre les lignes
d’ajout du handler et remplacer AddHandler par RemoveHandler)
Pour la petite histoire, nous créons un délégué à chaque fois que nous créons une procédure gestionnaire d'évènement avec le mot Handles ou avec AddHandler.
En C on utilise des pointeurs de fonction , adresse en mémoire indiquant ou le logiciel doit sauter quand on appelle une fonction ou un évènement. En VB on parle de délégué.
Création de menu contextuel par code:
Double-cliquez sur le composant ContextMenu dans la Boîte à outils pour l'ajouter sur le formulaire: Cela crée un ContextMenu1
Par code , on va le vider, puis ajouter des items (lignes) au menu, on indique le texte de l'item mais aussi quelque routine déclencher lorsque l'utilisateur clique sur le menu contextuel:
' Vide le context menu.
ContextMenu1.MenuItems.Clear()
' Ajoute une ligne 'Checked'.
ContextMenu1.MenuItems.Add("Ouvrir", New
System.EventHandler(AddressOf Me.Ouvrir_Click))
' Ajoute une ligne 'Checked
ContextMenu1.MenuItems.Add("Fermer", New System.EventHandler(AddressOf
Me.Fermer_Click))
' Test si le contrôle en cours est CheckBox,
si oui ajout d'un item "Contrôler".
If ContextMenu1.SourceControl Is CheckBox1 Then
ContextMenu1.MenuItems.Add("Contrôler", New System.EventHandler(AddressOf
Me.Controler_Click))
End If
Bien sur, il faut écrire les Sub Ouvrir_Click() Fermer_Click Controler_Click.
En fonctionnement, l'utilisateur Clique 'droit' sur un controle, le menu contextuel s'ouvre, il clique sur 'Ouvrir' ce qui exécute la routine Ouvrir_Click.
|
|
|
|
|