Cours VB.NETDate de mise à jour : 05/12/2010
X-A. Démarrer, arrêter un programme : Sub Main(), fenêtre Splash
X-A-1. Démarrer par un formulaire
X-A-2. Démarrer par Sub Main()
X-A-3. Fenêtre Splash
X-A-4. Comment arrêter le programme ?
X-A-5. Fin de programme : Attention !
X-B. Ouvrir plusieurs formulaires
X-B-1. Créer un formulaire en VB 2003
X-B-2. Créer un formulaire en VB 2005
X-B-3. Formulaire modal ou non modal
X-B-4. Dénomination des formulaires après leur création
X-B-5. Autres remarques sur les formulaires
X-B-5-a. Un formulaire est un objet : On peut ajouter des méthodes et des membres à un formulaire
X-B-5-b. Exemple plus complet : Afficher un formulaire
X-B-5-c. Récupération d'informations par DialogResult
X-B-5-d. Bouton par défaut
X-C. Faire communiquer les formulaires
X-C-1. Comment, à partir du premier formulaire, consulter un objet du second formulaire ?
X-C-1-a. En VB 2003 2005 2008 si on instancie le formulaire
X-C-1-a-i. Première solution
X-C-1-a-ii. Seconde solution
X-C-1-a-iii. Troisième solution
X-C-1-a-iv. Quatrième solution
X-C-1-b. En VB 2005, sans instanciation de formulaire
X-C-2. Comment, à partir du formulaire 'secondaire', connaître le formulaire 'propriétaire' ?
X-C-3. Les formulaires ouverts à partir de VB 2005
X-C-4. Utilisation de DialogResult
X-D. Créer une fenêtre 'multi documents'
X-D-1. Comprendre les programmes MDI
X-D-2. En VB 2003
X-D-2-a. Création de la fenêtre conteneur parent
X-D-2-b. Création des fenêtres filles
X-D-2-c. Comment connaître la fenêtre fille active ?
X-D-2-d. Comment avoir accès aux objets de la fenêtre fille à partir du conteneur ?
X-D-2-e. Comment parcourir toutes les fenêtres filles ?
X-D-2-f. Comment fermer toutes les fenêtres enfants ?
X-D-2-g. Comment avoir accès aux objets du conteneur à partir de la fenêtre fille ?
X-D-2-h. Comment une routine du module conteneur appelle une routine dans la fenêtre fille active ?
X-D-2-i. Agencement des fenêtres filles
X-D-3. En VB 2005 2008
X-A. Démarrer, arrêter un programme : Sub Main(), fenêtre Splash
Quand vous démarrez votre programme, quelle partie du code va être exécutée en premier?
En Vb 2003
Vous pouvez le déterminer en cliquant sur le menu Projet puis Propriétés de NomduProjet, une fenêtre Page de propriétés du projet s'ouvre.
Sous la rubrique Objet du démarrage, il y a une zone de saisie avec liste déroulante permettant de choisir:
-Le nom d'un formulaire du projet
ou
-Sub Main()
A partir de Vb 2005 (Framework 2) :
Ouvrir le 'Projet Designer', il est directement accessible dans l'explorateur de solution (Double cliquer sur 'My Projet')ou par le menu Projet-> Propriétés de ..:
On définit:
Le Formulaire de démarrage (startUp Form).
Si 'Activer l'infrastructure de l'application' est coché, l'élément de démarrage ne peut être qu'un formulaire; s'il est décoché, on peut lancer le programme par la Sub Main().
Attention: ne pas confondre Formulaire de démarrage en haut et Ecran de démarrage (écran splash) en bas.
X-A-1. Démarrer par un formulaire
Si vous tapez le nom d'un formulaire du projet, c'est celui-ci qui démarre : cette fenêtre est chargée au lancement du programme et la procédure Form_Load de cette fenêtre est effectuée.
En théorie, si vous avez une application avec un formulaire, le fait de dessiner ce formulaire crée une Classe Form1; il faudrait donc théoriquement créer une instance de ce formulaire (par un Dim MyForm As New Form1) pour lancer l'application.
En pratique, dessinez un formulaire, lancez l'exécution, ça marche car le runtime crée une instance du formulaire automatiquement à l'aide de sa méthode New et l'affiche (sans que l'on ai besoin de l'intancier soit même).
X-A-2. Démarrer par Sub Main()
C'est cette procédure Sub Main qui s'exécute en premier lorsque le programme est lancé.
Elle peut servir à ouvrir le formulaire de démarrage:
Exemple 1:
En mode design Form1 a été dessinée, C'est un modèle 'une Classe'.
Dans un module standard, dans une Sub Main(), on instancie initForm à partir de la Class Form1. Puis on affiche ce formulaire (cette fenêtre) avec .ShowDialog
Sub Main ()
Dim initForm As New Form1
initForm. ShowDialog ()
End Sub
|
Exemple 2:
Sub Main ()
Application. Run (New Form1 ())
End Sub
|
S'il y a plusieurs threads, Application.Run commence à exécuter une boucle de messages d'application standard sur le thread en cours et affiche le formulaire spécifié. Peut être utilisé aussi s'il y a un seul thread.
 |
Attention Sub Main() peut se trouver dans une Classe (Y compris une classe de formulaire) ou dans un module:
|
Si vous déclarez la procédure Main dans une classe, vous devez utiliser le mot clé Shared.
Class Form1
Public Shared Sub Main ()
. . . . .
End Sub
. .
End Classe
|
Dans un module, la procédure Main n'a pas besoin d'être partagée (Shared).
Module1
Sub Main ()
. . .
End Sub
End Module
|
Fonction Main():
On peut utiliser 'Function Main' (au lieu de 'Sub Main') qui retourne un Integer, que le système d'exploitation utilise comme code de sortie du programme. D'autres programmes peuvent tester ce code en examinant la valeur ERRORLEVEL Windows.
Function Main () As Integer
. . .
Return 0
End Function
|
Récupération de la ligne de commande:
Main peut également avoir comme argument un tableau de String. Chaque élément du tableau contient un des arguments de ligne de commande utilisée pour appeler le programme. Vous pouvez réaliser diverses actions en fonction de leurs valeurs.
Function Main (ByVal CmdArgs () As String ) As Integer
. . .
Return 0
End Function
|
On rappelle qu'en VB2005, si 'Activer l'infrastructure de l'application' est coché dans les propriétés du programme, le formulaire de démarrage ne peut être qu'un formulaire; s'il est décoché, on peut lancer le programme par la Sub Main().
Autre méthode de récupération de la ligne de commande en VB 2005:
On trouve les arguments de la ligne de commande dans My.Application.CommandLineArgs (VB 2005)
Exemple:
Cliquez sur un fichier de données, l'exécutable lié s'exécute et ouvre le fichier de données.
(Exemple: Quand on clique sur un fichier .bmp on lance automatiquement Paint qui charge l'image .bmp)
Il faut que l'extension du fichier soit liée avec le programme exécutable, si vous cliquez sur le fichier de données, cela lance l'exécutable.
Modifier l'extension liée Explorer->Outils-> Option des dossiers-> Type de fichiers
Dans Form_Load mettre:
If My. Application . CommandLineArgs . ToString < > " " Then
Dim i
For i = 0 To My. Application . CommandLineArgs . Count - 1
If mid (My. Application . CommandLineArgs (i). ToString ,1,2) " -o " Then
FileName = Mid (My. Application . CommandLineArgs (i). ToString , 3)
OpenFile ()
Exit For
End If
Next
End If
|
X-A-3. Fenêtre Splash
C'est une fenêtre qui s'ouvre au démarrage d'un programme, qui montre simplement une belle image, (pendant ce temps le programme peut éventuellement initialiser des données, ouvrir des fichiers...) ensuite la fenêtre 'Splash' disparaît et la fenêtre principale apparaît.
En Vb 2003 (Framework 1) il faut tout écrire:
Dans la Sub Main il est possible de gérer une fenêtre Splash.
Exemple:
Je dessine Form1 qui est la fenêtre Spash.
Dans Form2 qui est la fenêtre principale, j'ajoute:
Public Shared Sub Main()
Dim FrmSplash As New Form1
Dim FrmPrincipal As New Form2
FrmSplash. ShowDialog ()
FrmPrincipal. ShowDialog ()
End Sub
|
Dans Form1 (la fenêtre Splash)
Private Sub Form1_Activated
Me. Refresh ()
Me. Close ()
End Sub
|
On affiche FrmSplash un moment (Ho! la belle image) puis on l'efface et on affiche la fenêtre principale. Word, Excel.. font comme cela.
Autre méthode:
Public Sub main ()
Dim frmsplash As New frmsplash
Dim frmmain As New frmmain
frmsplash. Show ()
Application. DoEvents ()
System. Threading . Thread . Sleep (3000)
frmsplash. Close ()
Application. Run (frmmain)
End Sub
|
En Vb 2005 (Framework 2) c'est très simple:
Ouvrir le 'Projet Designer', il est directement accessible dans l'explorateur de solution (My Projet)ou par le menu Projet-> Propriétés de..:
Il faut que 'Activer l'infrastructure de l'application' soit coché:
On définit
Le formulaire de démarrage (startUp Form),
L'écran de démarrage (Splash Screen), il suffit d'indiquer son nom (En mode Run, VB l'affiche et le fait disparaître quand le formulaire de démarrage s'ouvre).
On peut aussi ajouter un écran splash tout fait:
Menu Projet, Ajouter un formulaire Windows, double cliquer sur 'formulaire de démarrage'.
On obtient:
Le nom de l'application, la version, le nom de la société sont automatiquement mis à jour en utilisant les 'Informations de l'assembly' accessible par un bouton situé dans le projet designer, en face du nom du formulaire de démarrage.
L'inconvénient de cet écran Splash automatique est qu'il s'affiche et s'efface très rapidement, avant de charger le formulaire de démarrage!! Pour le voir une seconde, j'ai ajouté à la fin de la procédure Form_Load de cet écran:
Me. Show ()
Application. DoEvents ()
System. Threading . Thread . Sleep (1000)
|
Autre solution: utiliser My.Application.MinimumSplashScreenDisplayTime, qui determine le temps d'affichage en ms. J'ai eu du mal à trouver où mettre l'instruction (dans le formulaire Splash ou Application_StartUp cela ne fonctionne pas!!
il faut mettre la ligne dans Application New (propriété du projet, onglet application, bouton 'Afficher les évènements de l'application", Liste déroulante à gauche 'MyApplication', liste déroulante à droite 'New'); rajouter la derniere ligne du code ci dessous.
Partial Friend Class MyApplication
< Global. System . Diagnostics . DebuggerStepThroughAttribute ()> _
Public Sub New ()
MyBase. New (Global. Microsoft . VisualBasic . ApplicationServices . AuthenticationMode . Windows )
Me. IsSingleInstance = false
Me. EnableVisualStyles = true
Me. SaveMySettingsOnExit = true
Me. ShutDownStyle = Global. Microsoft . VisualBasic . ApplicationServices . ShutdownMode . AfterMainFormCloses
End Sub
< Global. System . Diagnostics . DebuggerStepThroughAttribute ()> _
Protected Overrides Sub OnCreateMainForm ()
Me. MainForm = Global. WindowsApplication1 . Form1
End Sub
< Global. System . Diagnostics . DebuggerStepThroughAttribute ()> _
Protected Overrides Sub OnCreateSplashScreen ()
Me. SplashScreen = Global. WindowsApplication1 . SplashScreen1
My. Application . MinimumSplashScreenDisplayTime = 2000
End Sub
End Class
|
X-A-4. Comment arrêter le programme ?
Noter bien Me désigne le formulaire, la fenêtre en cours.
Vide la 'pompe à messages', ferme les formulaires. Si des fichiers sont encore ouvert, cela les ferme. (Il vaut mieux les fermer avant, intentionnellement.)
On peut aussi utiliser l'instruction End.
X-A-5. Fin de programme : Attention !
Outre l'usage de Application.Exit(), on peut terminer une application en fermant les formulaires, mais:
Dans Visual Basic 6.0, une application ne se terminait que lorsque tous les objets créés étaient détruits.
Dans Visual Basic .NET 2003, l'application se termine lorsque l'objet de démarrage est détruit. Si le formulaire que vous fermez est le formulaire de démarrage de votre application, votre application se termine. Si la procédure Sub_Main est définie comme objet de démarrage l'application se termine dès que le code de Sub_Main a fini de s'exécuter.
Depuis VB 2005 vous avez le choix entre les 2 solutions: terminer l'application quand le formulaire de démarrage est fermé ou quand tous les formulaires sont fermés.(dans l'application Designer voir 'Mode d'arrêt')
X-B. Ouvrir plusieurs formulaires
Comment à partir d'un formulaire 'Form1' ouvrir un second formulaire à partir de la Classe 'Form2' ?
Voici le plan du chapitre:
-En VB2003
-En VB 2005
-Formulaire modal et non modale.
-Comment se nomment les formulaires?
-Autres
-Un formulaire est un objet
-Exemple
-DialogResult
-Bouton par défaut
X-B-1. Créer un formulaire en VB 2003
A- Il faut d'abord créer la Classe Form2
Ajoutez un formulaire (Menu Projet, Ajouter un formulaire au projet), nommez le 'Form2' .
On se rend compte que quand on ajoute un formulaire (Form2 par exemple), on crée une nouvelle 'classe':
'Class Form2' qui hérite de System.Windows.Forms.Form , elle hérite donc de toutes les propriétés et méthodes de la Classe Form qui est la classe 'formulaire'.
Public Class Form2
Inherits System. Windows . Forms . Form
End Class
|
Elle contient du code généré automatiquement par le concepteur Windows Forms et les procédures liées aux évènements.
Dessinez dans Form2 les contrôles nécessaires.
B- Il faut créer ensuite le nouvel Objet formulaire, une instance de Form2:
Pour créer un nouveau formulaire dans le programme, il faut:
- Instancier un formulaire à partir du moule, de la Classe Form2 avec le mot New.
- Ouvrir ce formulaire, le faire apparaître, (avec ShowDialog, c'est un formulaire modal)
Dim formSecondaire As New Form2 ()
formSecondaire. ShowDialog ()
|
En résumé: on a Form1, on dessine Form2:
Pour que le bouton nommé "Créer Form secondaire" ouvre le second formulaire, il faut y mettre le code:
Private ButtonCreerFormSecondaire_Click ()
Dim formSecondaire As New Form2 ()
formSecondaire. ShowDialog ()
End Sub
|
 |
En conclusion:
Le fait d'ajouter un formulaire à un projet crée une Class, (un 'type' de formulaire, un moule) ce qui permet ensuite d'instancier (de créer) un objet formulaire.
|
VB 2003 est tolérant pour le premier formulaire: si on dessine un formulaire et ses contrôles et qu'on lance le programme, il accepte de fonctionner bien qu'on ait pas instancié le formulaire. Par contre, si on crée une seconde classe formulaire, il faut créer une instance de ce formulaire.
Dim formSecondaire As New Form2 ()
formSecondaire. ShowDialog ()
|
X-B-2. Créer un formulaire en VB 2005
Pas besoin d'instancier systématiquement un formulaire:
On peut utiliser la Class Form2 sans instancier, en utilisant directement le nom de la Classe:
On dessine Form2 (la classe) puis on peut écrire directement:
Private ButtonCreerFormSecondaire_Click ()
Form2. ShowDialog ()
End sub
|
On peut même utiliser les propriétés directement:
Form2. ForeColor = System. Drawing . Color . Coral
Form2. BackColor = System. Drawing . Color . Cyan
|
En fait, comme il n'y a pas d'instance de Form2, VB en crée une.
On peut aussi faire comme en VB 2003 en instancier le formulaire, mais c'est plus complexe.
X-B-3. Formulaire modal ou non modal
Un formulaire modal est un formulaire qui, une fois ouvert, prend la main, interdit l'usage des autres fenêtres. Pour poursuivre, on ne peut que sortir de ce formulaire.
Exemple typique: une MessageBox est un formulaire modal, les fenêtres d'avertissement dans Windows sont aussi modales.
Pour ouvrir un formulaire modal, il faut utiliser la méthode .ShowDialog
Dim f As New Form2
f. ShowDialog ()
|
ou en VB 2005
Noter, et c'est très important, que le code qui suit .showDialog est exécuté après la fermeture de la fenêtre modale.
Pour avoir un formulaire non modal faire:
Dim f As New Form2
f. Show ()
|
ou en VB 2005
Dans ce cas le formulaire f s'ouvre, le code qui suit .Show est exécuté immédiatement, et il est possible de passer dans une autre fenêtre de l'application sans fermer f.
Instance multiple: si un bouton1 contient le code:
Private Button1_Click
Dim f As New Form2
f. Show ()
End Sub
|
A chaque fois que l'on clique sur le bouton cela ouvre un formulaire: on peut en ouvrir plusieurs. On se retrouve avec X instances de Form2!!
Pour éviter cela:
- Utiliser ShowDialog
- Mettre Dim f As New Form2 dans la partie déclaration, ainsi il n'y aura qu'une instance de Form2. Le second click déclenche une erreur.
Class Form1
Dim f As New Form2
Private Button1_Click
f. Show ()
End Sub
End Class
|
X-B-4. Dénomination des formulaires après leur création
En VB 2003 et 2005 (avec instanciation d'un formulaire).
Une procédure qui est dans Form1 crée un formulaire par:
Class Form1
Private Buttonformsecondaire_Click ()
Dim formSecondaire As New Form2
End Sub
End Class
|
- Dans le formulaire formSecondaire créé:
Utiliser Me pour désigner le formulaire où on se trouve. (Form2 ou formSecondaire ne sont pas acceptés)
Exemple:
Me.Text= "Second formulaire" modifie le texte de la barre supérieure du formulaire
Le formulaire formSecondaire pourra être fermé par Me.close() dans le code du bouton Quitter par exemple.
- Hors du formulaire formSecondaire, dans la procédure où a été instancié le formulaire:
Utiliser formSecondaire pour désigner le formulaire.
Exemple:
Si la fenêtre appelante veut récupérer des informations dans le formulaire formSecondaire (un texte dans txtMessage par exemple), il faudra écrire.
Text=formSecondaire.txtMessage.Text
- Par contre, hors de la procédure qui a créée le formulaire, formSecondaire n'est pas accessible car on a crée le formulaire dans une procédure: cette instance du formulaire n'est visible que dans cette procédure. Pour rendre un formulaire accessible partout on peut écrire Public formSecondaire As New Form2 dans la zone générale avant les procédures.
Class Form1
Public formSecondaire As New Form2
Private Buttonformsecondaire_Click ()
End Sub
End Class
|
Exemple:
Class Form1
Sub MaRoutine ()
Dim formSecondaire As New Form2
Text= formSecondaire. TextBox . Text
End Sub
Sub AutreRoutine ()
. .
End Sub
End Class
|
Dans la procédure MaRoutine() le formulaire formSecondaire est visible et formSecondaire.TextBox est utilisable, pas dans la procédure AutreRoutine(). En résumé: Attention donc, si vous instanciez un formulaire dans une procédure, elle sera visible et accessible uniquement dans cette procédure.
Cela parait évident car un formulaire est un objet comme un autre et sa visibilité obéit aux règles habituelles ( J'ai mis malgré tout un certains temps à le comprendre!!).
 |
Un formulaire est un objet et sa visibilité obéit aux règles habituelles: Il peut être instancié dans une procédure, un module, précédé de 'Public' ,'Private'.. ce qui permet de gérer son accessibilité.
|
En VB 2005, sans instanciation des formulaires:
Par contre en VB 2005, si vous dessinez Form2 et que vous tapez:
Private ButtonCreerFormSecondaire_Click ()
Form2. Show ()
End sub
|
Vous pouvez utiliser dans Form1 les propriétés et contrôles de Form2 directement:
Form2. ForeColor = System. Drawing . Color . Coral
|
La Classe Form2 étant public , on a toujours accès au formulaire et aux contrôles.
(Par contre, on n'a pas accès aux procédures évènements qui sont 'Private')
Un exemple:
Dans Form1 Button1 affiche le formulaire Form2 (directement sans instanciation).
Dans la procédure Button2_Click de Form1 on a accès au TextBox qui est dans Form2:
X-B-5. Autres remarques sur les formulaires
X-B-5-a. Un formulaire est un objet : On peut ajouter des méthodes et des membres à un formulaire
On a vu que, en fait, il y a création d'une Classe quand on dessine un formulaire, et bien comme dans un module de Classe (on verra cela plus loin), on peut ajouter des propriétés et des méthodes.
Pour ajouter une méthode à un formulaire, il faut créer une Sub Public dans le corps de la fenêtre:
Class Form1
Public Sub Imprime ()
Code d
End Sub
End Class
|
Si une instance de la fenêtre se nomme F, F.Imprime() exécute la méthode Imprime (donc la sub Imprime())
De même, pour définir un membre d'un formulaire, il faut ajouter une variable 'public'.
Public Utilisateur As String
|
Permet d'utiliser en dehors du formulaire F.Utilisateur
X-B-5-b. Exemple plus complet : Afficher un formulaire
Comment savoir si un formulaire existe, s'il n'existe pas le créer, s'il existe le rendre visible et lui donner la main :
If f Is Nothing Then
f = New Form2
f. ShowDialog ()
Else
If f. Visible = False Then
f. Visible = True
End If
f. Activate ()
End If
|
Autre solution plus complète gérant aussi la taille du formulaire:
Si le formulaire existe et n'a pas été 'disposed'(détruit), le mettre à la taille normale et en avant.
If Not IsNothing (F) Then
If Not F. IsDisposed Then
F. WindowState = FormWindowState. Normal
F. BringToFront ()
Else
F = New Form3
F. Show ()
End If
Else
F = New Form3
F. Show ()
End If
|
(Merci Michel de Montréal)
X-B-5-c. Récupération d'informations par DialogResult
On ouvre un formulaire modal, comment, après sa fermeture, récupérer des informations sur ce qui s'est passé dans ce formulaire modale?
Par exemple, l'utilisateur a t-il cliqué sur le bouton Ok ou le bouton Cancel pour fermer le formulaire modale?
Pour cela on va utiliser une propriété DialogResult des boutons, y mettre une valeur correspondant au bouton, quand l'utilisateur clique sur un bouton, la valeur de la propriété DialogResult du bouton est assignée à la propriété DialogResult du formulaire, on récupère cette valeur à la fermeture du formulaire modal.
Dans le formulaire modal Form2 on met
ButtonOk. DialogResult = DialogResult. ok
ButtonCancel. DialogResult = DialogResult. Cancel
|
Dans le formulaire qui appelle:
Form2. ShowDialog ()
If form2. DialogResult = DialogResult. ok then
End if
|
Remarque:
- On utilise comme valeur de DialogResult les constantes de l'énumération DialogResult:DialogResult.ok .Cancel .No .Yes .Retry .None .Abort .Ignore.
- Si l'utilisateur clique sur la fermeture du formulaire modal (bouton avec X) cela retourne DialogResult.cancel
- on peut aussi utiliser la syntaxe: If form2.ShowDialog(Me) = System.Windows.Forms.DialogResult.OK Then qui permet en une seule ligne d'ouvrir form2 et de tester si l'utilisateur a cliqué sur le bouton ok de form2.
- La fermeture du formulaire modal par le bouton de fermeture ou l'appel de la méthode Close ne détruit pas toujours le formulaire modal, il faut dans ce cas utiliser la méthode Dispose pour le détruire.
X-B-5-d. Bouton par défaut
Parfois dans un formulaire, l'utilisateur doit pouvoir, valider (taper sur la touche 'Entrée') pour accepter et quitter rapidement le formulaire (c'est l'équivalent du bouton 'Ok') ou taper 'Echap' pour sortir du formulaire sans accepter (c'est l'équivalent du bouton 'Cancel').
Il suffit pour cela de donner aux propriétés AcceptButton et CancelButton du formulaire,le nom des boutons ok et cancel qui sont sur la feuille.
form1. AcceptButton = buttonOk
form1. CancelButton = buttonCancel
|
Si l'utilisateur tape la touche 'Echap' la procédure buttonCancel_Click est exécutée.
X-C. Faire communiquer les formulaires
 Rappel:Formulaire=fenêtre
Comment faire communiquer 2 formulaires?+++
- Comment à partir d'un formulaire consulter un objet d'un autre formulaire?
- Comment à partir du second formulaire connaître le formulaire propriétaire?
- Les formulaires ouverts en VB 2005
Cette question est fréquemment posée et créée beaucoup de problèmes!!
X-C-1. Comment, à partir du premier formulaire, consulter un objet du second formulaire ?
Un premier formulaire en ouvre un second, dans le second saisir un texte, puis l'afficher dans le premier.
X-C-1-a. En VB 2003 2005 2008 si on instancie le formulaire
Reprenons toujours le même exemple: le premier formulaire (Class Form1) crée une instance de Form2 (L'utilisateur du programme clique sur ButtonCreerformsecondaire de Form1) cela crée formSecondaire. formSecondaire contient un textbox nommé TextBox2. L'utilisateur saisit un texte dans le textbox2 et quitte formsecondaire. Comment Form1 peut-il récupérer TextBox2.text et l'afficher dans un label1.
La Class Form1 contient un Button1 "Créer Form2" et contient un Label1.
La Class Form2 aura une instance: formsecondaire, elle contient TextBox2 et un Button2 "Quitter".
X-C-1-a-i. Première solution
Pour qu'un formulaire puisse utiliser les objets d'un autre formulaire, il faut que le second formulaire soit visible.
Créer un formulaire formSecondaire en utilisant la Classe Form2.
Class Form1
Sub buttonCreerformsecondaire_Click
Dim formSecondaire As New form2 ()
formSecondaire. ShowDialog ()
label1. Text = formSecondaire. TextBox2 . Text
End Sub
End Class
|
formSecondaire n'est visible QUE dans button1_Click+++
Les contrôles de Form2 sont Public ce qui permet d'y avoir accès.
On peut se poser la question de savoir si après ShowDialog le formulaire modal formSecondaire existe encore?
La ruse c'est de mettre dans le code du bouton Quitter de Form2 Me.Hide() pour rendre la fenêtre Form2 invisible mais accessible (et pas Me.Close() qui détruirait la fenêtre, le contrôle txtMessage et son contenu).
Dim formSecondaireAs New Form2 ()
formSecondaire. ShowDialog ()
label1. Text = formSecondaire. TextBox2 . Text
formSecondaire. Close ()
|
Une fois que le texte à été récupéré, on fait disparaître le formulaire formSecondaire.
En réalité, curieusement, il semble que les propriétés de formSecondaire soient accessibles même après un Close!! Cela vient du fait que, bien que le formulaire soit fermé, il n'est pas encore détruit.
Si vous voulez créer un formulaire Form2 qui soit visible dans la totalité d'un formulaire Form1, il faut l'instancier dans la partie déclaration du formulaire Form1:
Class Form1
Public formSecondaire As New Form2 ()
Sub buttoncreerformsecondaire_Click
formSecondaire. ShowDialog ()
label1. Text = formSecondaire. TextBox2 . Text
End Sub
End Class
|
On peut ainsi l'ouvrir par formSecondaire.ShowDialog() dans une procédure et lire une zone texte dans une autre procédure.
X-C-1-a-ii. Seconde solution
Si vous voulez créer un formulaire qui soit visible dans la totalité du programme et dont les contrôles ou propriétés soient accessibles par l'ensemble du programme, il faut l'instancier dans un module standard (Les puristes vont pas aimer!!):
Module MonModule
Public formSecondaire As New Form2 ().
End Module
Class Form3
Sub Buttoncreerformsecondaire_Click
formSecondaire. ShowDialog ()
End Sub
Sub Button2_Click
label1. Text = formSecondaire. TextBox2 . Text
End Sub
End Class
|
On peut avoir accès au TextBox2 n'importe ou!!
C'est un objet 'Public' et on n'aime pas bien!!!
X-C-1-a-iii. Troisième solution
On peut créer dans le second formulaire un objet Public Shared:
Class Form2
Public Shared MonTextBox As TextBox
Private Sub Button2_Click
MonTextBox = TextBox1
Me. Close ()
End Sub
End Class
|
Dans Form1
Class Form1
Sub buttoncreerformsecondaire_Click
Dim formSecondaire As New form2 ()
formsecondaire. ShowDialog ()
Label1. Text = formsecondaire. MonTextBox . Text ()
End Sub
End Class
|
Noter que contrairement aux exemples donnés par certains sites, il faut bien écrire: formsecondaire.MonTextBox.Text() et pas Form2.MonTextBox.Text() du moins en VS 2003.
Cette troisième solution a le même principe que la première, en plus compliqué!!
On peut simplement retenir que si formsecondaire est visible, seuls ses membres publiques sont visibles bien entendu: par exemple ses propriétés, ses contrôles, les procédures publiques, PAS les procédures événementielles qui sont privées.
Dans le même ordre d'idée, on peut créer une Property Public:
Class Form2
Public ReadOnly Property LeText () As String
Get
Return TextBox2. Text
End Get
End Property
End Class
Class Form1
Sub button1_Click
Dim formSecondaire As New form2 ()
formsecondaire. ShowDialog ()
Label1. Text = formsecondaire. LeText
End Sub
End Class
|
Même conclusion, mais il faut toujours utiliser formsecondaire qui doit être visible , c'est ça l'important!!
X-C-1-a-iv. Quatrième solution
Créer une variable ou une Classe 'Public' (dite 'Globale') et y faire transiter les données :
Module MonModule
Public BAL As String
End Module
Class Form2
Private Sub Button2_Click
BAL = TextBox2. Text
Me. Close ()
End Sub
End Class
Class Form1
Sub Button1_Click
formSecondaire. ShowDialog ()
label1. Text = BAL
End Sub
End Class
|
Cela a tous les inconvénients: c'est une variable globale, source d'erreur, n'importe quel formulaire peut écrire dans BAL...
C'est très mal de faire cela.
Mais c'est simple et cela marche bien.
X-C-1-b. En VB 2005, sans instanciation de formulaire
Par contre en VB 2005, si vous dessinez Form2 et que vous tapez:
Private ButtonCreerFormSecondaire_Click ()
Form2. Show ()
End sub
|
Vous pouvez utiliser dans Form1 les propriétés et contrôles de Form2 directement:
Label1. Text = Form2. TextBox2 . Text
|
La Classe Form2 étant public , on a toujours accès au formulaire et aux contrôles.
(Par contre, on n'a pas accès aux procédures évènements qui sont 'Private'; on peut d'ailleurs les mettre 'Public' pour y avoir accès)
X-C-2. Comment, à partir du formulaire 'secondaire', connaître le formulaire 'propriétaire' ?
Exemple : Comment savoir quel formulaire a ouvert le formulaire en cours ?
ShowDialog possède un argument facultatif, owner, qu'on peut utiliser afin de spécifier une relation 'propriétaire'-'formulaire en cours'. Par exemple, lorsque le code de votre formulaire principal ouvre un formulaire, vous pouvez passer Me comme propriétaire de la boîte de dialogue, afin de désigner votre formulaire principal comme propriétaire, comme le montre le code de l'exemple suivant :
Dans Form1
Dim formSecondaire As New Form2
f. ShowDialog (Me)
|
Dans Form2
On peut récupérer le nom du 'propriétaire', qui a ouvert la fenêtre.
Il est dans Owner,et on peut par exemple afficher son nom.
Par exemple:
Label1. text = Me. Owner . ToString
|
Cela affiche: NomApplication.NomFormulaire,Texte de la barre de titre.
Owner a toutes les propriétés (Name, Location, Controls..) d'un formulaire car il hérite de Form. , mais on ne peut pas consulter les contrôles de Owner directement. Il faut d'abord caster owner qui est une Form en Form1, ensuite on peut avoir accès aux contrôles de Form1.
Dim f As Form1 = CType (Me. Owner , Form1)
Label1. Text () = f. Button1 . Text
|
Comment obtenir le nom du formulaire propriétaire? Autre méthode.
Une autre méthode consiste à surcharger le constructeur de la Form2 afin qu'il accepte un paramètre qui indique le propriétaire ( nom de l'instance de Form1):
Dans Form1: Lors de l'instanciation de la form2 il faut écrire:
Dim FormSecondaire As New Form2 (Me)
FormSecondaire . ShowDialog (Me)
|
Dans Form2:
Private FormProp As Form1
Public Sub New (ByVal NomForm As Form1)
MyBase. New ()
FormProp = NomForm
InitializeComponent ()
End Sub
|
On crée donc dans Form2 une variable FormProp qui indique la form propriétaire.
Pour appeler une méthode de form1 à partir de FormSecondaire (Form2):
L'inconvénient de toutes ces méthodes est qu'il faut connaître la classe du formulaire propriétaire (Form1 ici).
X-C-3. Les formulaires ouverts à partir de VB 2005
- My.Application.OpenForms contient les formulaires ouverts.
Afficher le texte contenu dans la barre de titre du formulaire nommé 'Form3'.
MyTextBox. Text = My. Application . OpenForms (" Form3 " )
|
Afficher le texte contenu dans la barre de titre du premier formulaire ouvert.
MyTextBox. Text = My. Application . OpenForms (0)
|
Exemple: rajouter le texte 'ouvert' à la barre de tache des formulaires ouverts:
For Each F As System. Windows . Forms . Form In My. Application . OpenForms
F. Text + = " [ouvert] "
Next
|
- My.Forms contient tous les formulaires.
Afficher le texte contenu dans la barre de titre du formulaire Form1.
MyTextBox. Text = My. Forms . Form1 . Text
|
Remarquons qu'il est interdit d'utiliser My.Forms.Form1 si on est dans Form1 .(il faut utiliser Me)
-Différence avec My.Application.OpenForms(0)?
Dim f As New Form1
f. Text = " hello "
f. Show ()
TextBox1. Text = My. Forms . Form1 . Text
|
Affiche 'Form1' qui est le texte de la barre par défaut en design (celui de la Classe Form1).
TextBox2. Text = My. Application . OpenForms (" Form1 " ). Text
|
X-C-4. Utilisation de DialogResult
Si un formulaire Form1 ouvre un formulaire modal nommé Dialog1, il y a un moyen élégant pour le formulaire Form1 de récupérer une information du formulaire Dialog1 quans ce dernier est fermé (il est modal).
Dans le formulaire modal Dialog1, si l'utilisateur clique sur le bouton Ok, on met
Sub ButtonOk_Click
ButtonOk. DialogResult = DialogResult. ok
End Sub
|
Dans Form1 on a:
Dialog1. ShowDialog ()
If Dialog1. DialogResult = DialogResult. Ok then
End if
|
Les seules valeurs possibles pour DialogResult sont Ok, Cancel, Yes, No, None, Abort, Ignore, Retry. On ne peut malheureusement pas utiliser une autre valeur
X-D. Créer une fenêtre 'multi documents'
Comment créer un programme MDI (Multi Document Interface) en VB 2003 puis en VB 2005 ?
X-D-1. Comprendre les programmes MDI
L'exemple de Word : la fenêtre principale (fenêtre MDI) contient les menus en haut, on peut ouvrir plusieurs documents dans des fenêtres filles.
Ci dessous l'exemple de LDF (Programme de comptabilité écrit par l'auteur):
 On a une fenêtre MDI (conteneur) contenant 2 fenêtres filles affichant chacune une année de comptabilité.
Dans VB.NET, un MDIForm (fenêtre principale MDI) est une fenêtre quelconque dont la propriété :
IsMDIContainer = True.
Dans la fenêtre fille, la propriété MDIParent indique le conteneur (C'est à dire le nom de la fenêtre MDI) .
Les applications MDI peuvent avoir plusieurs conteneurs MDI.
Une fenêtre principale MDI peut contenir plusieurs fenêtres filles de même type ou de type différente.
X-D-2. En VB 2003
X-D-2-a. Création de la fenêtre conteneur parent
Exemple d'un programme MDI.
On va créer une Form1 qui est le conteneur.
Une Form2 qui est la fenêtre fille.
Dans Form1 le menu principal contient la ligne '&Nouvelle' qui crée une nouvelle instance de la fenêtre fille.
Créer la fenêtre Form1 :
Dans la fenêtre Propriétés, affectez la valeur True à la propriété IsMDIContainer. Ce faisant, vous désignez la fenêtre comme le conteneur MDI des fenêtres enfants.
Remarque: Affecter la valeur Maximized à la propriété WindowState, car il est plus facile de manipuler des fenêtres MDI enfants lorsque le formulaire parent est grand. Sachez par ailleurs que le formulaire MDI parent prend la couleur système (définie dans le Panneau de configuration Windows).
Ajouter les menus du conteneur :
A partir de la boîte à outils, faire glisser un contrôle MainMenu sur le formulaire. Créer un élément de menu de niveau supérieur en définissant la propriété Text avec la valeur &File et des éléments de sous-menu appelés &Nouvelle et &Close. Créer également un élément de menu de niveau supérieur appelé &Fenêtre.
Dans la liste déroulante située en haut de la fenêtre Propriétés, sélectionnez l'élément de menu correspondant à l'élément &Fenêtre et affectez la valeur true à la propriété MdiList. Vous activez ainsi le menu Fenêtre qui permet de tenir à jour une liste des fenêtres MDI enfants ouvertes et indique à l'utilisateur par une coche la fenêtre enfant active.
Il est conseillé de créer un module standard qui contient une procédure Main qui affiche la fenêtre principale:
Module StandartGénéral
Public FrmMDI as Form1
Sub Main ()
FrmMDI. ShowDialog ()
End sub
End Module
|
Noter bien que FrmMDI est donc la fenêtre conteneur et est Public donc accessible à tous.
X-D-2-b. Création des fenêtres filles
Pour créer une fenêtre fille, il suffit de donner à la propriété MDIParent d'une fenêtre le nom de la fenêtre conteneur.
Dessiner dans Form2 les objets nécessaire dans la fenêtre fille.
Comment créer une instance de la fenêtre fille à chaque fois que l'utilisateur clique sur le menu '&Nouvelle'?
En premier lieu, déclarez dans le haut du formulaire Form1 (accessible dans tout le formulaire) une variable nommée MDIFilleActive de type 'Form2' qui contient la fenêtre fille active.
Dim MDIFilleActive As Form2
|
La routine correspondant au MenuItem &Nouvelle (dans la fenêtre MDI) doit créer une instance de la fenêtre fille :
Protected Sub MDIChildNouvelle_Click (ByVal sender As System. Object , ByVal e As System. EventArgs )
_Handles MenuItem2. Click
MDIFilleActive = New Form2 ()
MDIFilleActive. MdiParent = Me
MDIFilleActive. Show ()
End Sub
|
Ainsi l'utilisateur peut ouvrir plusieurs fenêtres filles.
X-D-2-c. Comment connaître la fenêtre fille active ?
Quand on en a ouvert plusieurs?
La fenêtre fille active est dans Me.ActiveMdiChild du conteneur
Comment voir s'il existe une fenêtre active?
If Not Me. ActiveMdiChild Is Nothing then
|
En mettant dans la variable MDIFilleActive la fenêtre active, on est sûr de l'avoir toujours à disposition: pour cela dans la procédure Form1_MdiActivate de la fenêtre MDI (qui se produit à chaque fois que l'on rentre dans la fenêtre fille avec la souris, le menu..) je récupère Me.ActiveMdiChild qui retourne la fenêtre fille active.
Dans Form1:
Private Sub Form1_MdiChildActivate. .
MDIFilleActive= Me. ActiveMdiChild
End Sub
|
 |
Il faut comprendre que peut importe le nom de la fenêtre fille active, on sait simplement que la fenêtre fille active est dans MIDFilleActive, variable que l'on utilise pour travailler sur cette fenêtre fille.
|
X-D-2-d. Comment avoir accès aux objets de la fenêtre fille à partir du conteneur ?
De la fenêtre conteneur j'ai accès aux objets de la fenêtre fille par l'intermédiaire de la variable MDIFilleActive précédemment mise à jour; par exemple le texte d'un label:
MDIFilleActive. label1 . text
|
Comment avoir accès à des éléments de cette fenêtre fille, une sub Affichetotaux par exemple à partir de ActiveMdiChild:
Si je tape Me.ActiveMdiChild.AfficheTotaux cela plante!! (car ActiveMdiChild est une instance de la classe Form).
Il faut écrire: CType(ActiveMdiChild, Form2).Affichetotaux() (car il faut convertir ActiveMdiChild en classe Form2)
X-D-2-e. Comment parcourir toutes les fenêtres filles ?
La collection MdiChildren contient toutes les fenêtres filles, on peut les parcourir:
Dim ff As Form2
For Each ff In Me. MdiChildren
. . .
Next
|
Cela est valable s'il n'y a qu'un type de formulaire permettant de créer des formulaires enfants (Form2 par exemple)
Mais si on a 2 formulaires Form2 et Form3 cela se complique.
dim i_form as Form
dim i_form3 as form3
dim i_form2 as form2
For Each i_form In Me. mdichildren
if typeof i_form is form2 then
i_form2 = ctype (i_form,form2)
msgbox i_form2. property_du_form2
end if
if typeof i_form is form3 then
i_form1 = ctype (i_form,form3)
msgbox i_form3. property_du_form3
end if
next
|
Merci Gaël.
X-D-2-f. Comment fermer toutes les fenêtres enfants ?
Dim form As Form
For Each form In Me. MdiChildren
form. Close ()
Next
|
X-D-2-g. Comment avoir accès aux objets du conteneur à partir de la fenêtre fille ?
En utilisant Me.MdiParent qui contient le nom du conteneur.
Dans la fenêtre fille le code Me.MdiParent.text ="Document 1" affichera 'Document 1' dans la barre de titre du conteneur.
X-D-2-h. Comment une routine du module conteneur appelle une routine dans la fenêtre fille active ?
Si une routine public de la fenêtre fille se nomme Affiche, on peut l'appeler par:
Il n'est pas possible d'appeler les évènements liés aux objets de la fenêtre fille, par contre la routine Affiche() dans notre exemple peut le faire.
X-D-2-i. Agencement des fenêtres filles
La propriété LayoutMdi de la fenêtre conteneur modifie l'agencement des fenêtres filles.
0 - MdiLayout.Cascade
1 - MdiLayout.TileHorizontal
2 - MdiLayout.TileVertical
3 - MdiLayout.ArrangeIcons
Exemple:
Le menu Item Cascade met les fenêtres filles en cascade.
Protected Sub CascadeWindows_Click (ByVal sender As System. Object , ByVal e As System. EventArgs )
Me. LayoutMdi (System. Windows . Forms . MdiLayout . Cascade )
End Sub
|
X-D-3. En VB 2005 2008
90% du travail est fait automatiquement: c'est merveilleux!!
Dans l'explorateur de solution: Click droit sur le nom du programme ('mdi' ici):
Dans le menu, passer par 'Ajouter' puis 'Formulaire Windows':
Cliquer sur 'MDI Parent Form' ('Formulaire Parent MDI')
On obtient un formulaire MDI parent avec les menus, la barre d'icône, d'état, les menus déroutants avec image:
(Le logiciel a rajouté les 4 outils en bas, nécessaire pour réaliser l'interface.)
Le code qui génère les formulaires enfants est automatiquement crée:
Public Class MDIParent1
Private Sub ShowNewForm (ByVal sender As Object, ByVal e As EventArgs) Handles NewToolStripMenuItem. Click ,
_NewToolStripButton. Click , NewWindowToolStripMenuItem. Click
Dim ChildForm As New System. Windows . Forms . Form
ChildForm. MdiParent = Me
m_ChildFormNumber + = 1
ChildForm. Text = " Window " & m_ChildFormNumber
ChildForm. Show ()
End Sub
Private Sub ExitToolsStripMenuItem_Click (ByVal sender As Object, ByVal e As EventArgs)
_Handles ExitToolStripMenuItem. Click
Global. System . Windows . Forms . Application . Exit ()
End Sub
Private Sub CascadeToolStripMenuItem_Click (ByVal sender As Object, ByVal e As EventArgs)
_Handles CascadeToolStripMenuItem. Click
Me. LayoutMdi (MdiLayout. Cascade )
End Sub
Private Sub TileVerticleToolStripMenuItem_Click (ByVal sender As Object, ByVal e As EventArgs)
_Handles TileVerticalToolStripMenuItem. Click
Me. LayoutMdi (MdiLayout. TileVertical )
End Sub
Private Sub TileHorizontalToolStripMenuItem_Click (ByVal sender As Object, ByVal e As EventArgs)
_Handles TileHorizontalToolStripMenuItem. Click
Me. LayoutMdi (MdiLayout. TileHorizontal )
End Sub
Private Sub ArrangeIconsToolStripMenuItem_Click (ByVal sender As Object, ByVal e As EventArgs)
_Handles ArrangeIconsToolStripMenuItem. Click
Me. LayoutMdi (MdiLayout. ArrangeIcons )
End Sub
Private Sub CloseAllToolStripMenuItem_Click (ByVal sender As Object, ByVal e As EventArgs)
_Handles CloseAllToolStripMenuItem. Click
For Each ChildForm As Form In Me. MdiChildren
ChildForm. Close ()
Next
End Sub
Private m_ChildFormNumber As Integer = 0
End Class
|
Les sources présentés sur cette page sont libres de droits,
et vous pouvez les utiliser à votre convenance. Par contre cette page de présentation de ces sources constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © .
Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu :
textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
Cette page est déposée à la SACD.
|