Cours VB.NET

Image non disponible


précédentsommairesuivant

X-A. Démarrer, arrêter un programme : Sub Main(), fenêtre Splash

Image non disponible

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).

Image non disponible

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

 
Sélectionnez

Sub Main()

        Dim initForm As New Form1

        initForm.ShowDialog()

End Sub

Exemple 2:

 
Sélectionnez

Sub Main() 
' Démarre l' application et affiche une instance de Form1
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.

 
Sélectionnez

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).

 
Sélectionnez

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.

 
Sélectionnez

Function Main() As Integer
...
Return 0 ' Zéro signifie : tout est Ok.
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.

 
Sélectionnez

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:

 
Sélectionnez

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 
' dans le cas ou la ligne de commande contient le nom du fichier à lancer et '-o'

FileName = Mid(My.Application.CommandLineArgs(i).ToString, 3)

OpenFile() ' charger les données

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.

Image non disponible

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()

 
Sélectionnez

Dim FrmSplash As New Form1    'instance la fenêtre Splash 

Dim FrmPrincipal As New Form2 'instance la feuille principale

FrmSplash.ShowDialog()        'affiche la fenêtre Splash en Modale


FrmPrincipal.ShowDialog()     'a la fermeture de Splash,  affiche la fenêtre principale

End Sub

Dans Form1 (la fenêtre Splash)

 
Sélectionnez

Private Sub Form1_Activated

Me.Refresh() 'pour afficher totalement la fenêtre.

'ici ou on fait plein de choses on ouvre des fichiers ou on perd du temps.

' s'il n'y a rien a faire on met un Timer pour que l'utilisateur admire la belle image.

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:

 
Sélectionnez

Public Sub main() 


'création des formulaires frmmain and frmsplash avec le designer 

Dim frmsplash As New frmsplash 

Dim frmmain As New frmmain 

 

'on affiche la Splash

frmsplash.Show() 

Application.DoEvents() 

 

'On attend (3000 milliseconds) 

System.Threading.Thread.Sleep(3000) 

 

'On efface la Splash

frmsplash.Close() 

 

'On affiche le formulaire principal

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).

Image non disponible

On peut aussi ajouter un écran splash tout fait:

Menu Projet, Ajouter un formulaire Windows, double cliquer sur 'formulaire de démarrage'.

On obtient:

Image non disponible

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:

 
Sélectionnez

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.

 
Sélectionnez

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 '<= A rajouter
        End Sub
    End Class

X-A-4. Comment arrêter le programme ?

 
Sélectionnez

Me.Close()    'Ferme la fenêtre en cours

Noter bien Me désigne le formulaire, la fenêtre en cours.

 
Sélectionnez

Application.Exit()    'Ferme l'application

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'.

 
Sélectionnez

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)
 
Sélectionnez

Dim formSecondaire As New Form2()

formSecondaire.ShowDialog()  

En résumé: on a Form1, on dessine Form2:

Image non disponible

Pour que le bouton nommé "Créer Form secondaire" ouvre le second formulaire, il faut y mettre le code:

 
Sélectionnez

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.

 
Sélectionnez

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:

 
Sélectionnez

Private ButtonCreerFormSecondaire_Click()
    Form2.ShowDialog()
End sub
Image non disponible

On peut même utiliser les propriétés directement:

 
Sélectionnez

 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

 
Sélectionnez

Dim f As New Form2           

f.ShowDialog()

ou en VB 2005

 
Sélectionnez

form2.ShowDialog()

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:

 
Sélectionnez

Dim f As New Form2      

f.Show() 

ou en VB 2005

 
Sélectionnez

form2.Show()

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:

 
Sélectionnez

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.
 
Sélectionnez

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:

 
Sélectionnez

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.
 
Sélectionnez

Class Form1
Public formSecondaire As New Form2
Private Buttonformsecondaire_Click ()    

    

End Sub
End Class

Exemple:

 
Sélectionnez

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:

 
Sélectionnez

Private ButtonCreerFormSecondaire_Click()
    Form2.Show()
End sub

Vous pouvez utiliser dans Form1 les propriétés et contrôles de Form2 directement:

 
Sélectionnez

 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:

Image non disponible

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:

 
Sélectionnez

Class Form1

Public Sub Imprime()

    Code d'impression

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'.

 
Sélectionnez

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 :

 
Sélectionnez

        If f Is Nothing Then    'Si f=rien 

            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.

 
Sélectionnez

        If Not IsNothing(F) Then
            'Si on en a pas déjà disposé
            If Not F.IsDisposed Then
                F.WindowState = FormWindowState.Normal  ' Optional
                F.BringToFront()  '  Optional
            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

 
Sélectionnez

 ButtonOk.DialogResult= DialogResult.ok

 

 ButtonCancel.DialogResult= DialogResult.Cancel

Dans le formulaire qui appelle:

 
Sélectionnez

Form2.ShowDialog()

If form2.DialogResult= DialogResult.ok then

    'l'utilisateur a cliqué sur le bouton ok

End if
Remarque:
  1. On utilise comme valeur de DialogResult les constantes de l'énumération DialogResult:DialogResult.ok .Cancel .No .Yes .Retry .None .Abort .Ignore.
  2. Si l'utilisateur clique sur la fermeture du formulaire modal (bouton avec X) cela retourne DialogResult.cancel
  3. 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.
  4. 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.

 
Sélectionnez

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
Rappel:Formulaire=fenêtre
Comment faire communiquer 2 formulaires?+++
  1. Comment à partir d'un formulaire consulter un objet d'un autre formulaire?
  2. Comment à partir du second formulaire connaître le formulaire propriétaire?
  3. 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".

Image non disponible

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.

 
Sélectionnez

Class Form1

Sub buttonCreerformsecondaire_Click

  Dim formSecondaire As New form2 ()    'On crée formSecondaire

  formSecondaire.ShowDialog()           'On ouvre formSecondaire

  label1.Text=formSecondaire.TextBox2.Text 'On récupère le texte de TextBox1

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).

 
Sélectionnez

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:

 
Sélectionnez

Class Form1

    Public formSecondaire As New Form2()

    

Sub buttoncreerformsecondaire_Click

  formSecondaire.ShowDialog()           'On ouvre formSecondaire

  label1.Text=formSecondaire.TextBox2.Text 'On récupère le texte de TextBox1

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!!):

 
Sélectionnez

Module MonModule

    Public formSecondaire As New Form2().

End Module




Class Form3

Sub Buttoncreerformsecondaire_Click

    formSecondaire.ShowDialog()
    'ou MonModule.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:

 
Sélectionnez

Class Form2

Public Shared MonTextBox As TextBox

Private Sub Button2_Click 'Bouton quitter

MonTextBox = TextBox1    'On affecte à l'objet MonTexBox le TextBox1

Me.Close()

End Sub

End Class

Dans Form1

 
Sélectionnez

Class Form1

Sub buttoncreerformsecondaire_Click

Dim formSecondaire As New form2 ()    'On crée formSecondaire

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:

 
Sélectionnez

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 ()    'On crée formSecondaire

formsecondaire.ShowDialog()

Label1.Text = formsecondaire.LeText   'On utilise la property

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 :

 
Sélectionnez

Module MonModule

    Public BAL As String     'Variable Public dite 'Boite aux lettres'

End Module

Class Form2

Private Sub Button2_Click 'Bouton quitter

BAL = TextBox2.Text    'On met TextBox1.Text dans BAL

Me.Close()

End Sub

End Class

 

Class Form1

Sub Button1_Click

    formSecondaire.ShowDialog()

    label1.Text= BAL    'On récupère ce qui est dans 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:

 
Sélectionnez

Private ButtonCreerFormSecondaire_Click()
    Form2.Show()
End sub

Vous pouvez utiliser dans Form1 les propriétés et contrôles de Form2 directement:

 
Sélectionnez

 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

 
Sélectionnez

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:

 
Sélectionnez

    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.

 
Sélectionnez

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:

 
Sélectionnez

Dim FormSecondaire As New Form2(Me) 
FormSecondaire .ShowDialog(Me) 'affichage modal de la form2

Dans Form2:

 
Sélectionnez

 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):

 
Sélectionnez

FormProp.MaRoutine()

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'.

 
Sélectionnez

MyTextBox.Text= My.Application.OpenForms("Form3")

Afficher le texte contenu dans la barre de titre du premier formulaire ouvert.

 
Sélectionnez

MyTextBox.Text= My.Application.OpenForms(0)

Exemple: rajouter le texte 'ouvert' à la barre de tache des formulaires ouverts:

 
Sélectionnez

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.

 
Sélectionnez

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)?

 
Sélectionnez

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).

 
Sélectionnez

TextBox2.Text = My.Application.OpenForms("Form1").Text    

'Affiche 'hello' qui est le texte de l'instance f

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

 
Sélectionnez

 Sub ButtonOk_Click
 ButtonOk.DialogResult= DialogResult.ok
End Sub

Dans Form1 on a:

 
Sélectionnez

'On ouvre le formulaire Dialog1
Dialog1.ShowDialog()

If Dialog1.DialogResult= DialogResult.Ok then

    'l'utilisateur a cliqué sur le bouton ok

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'

Image non disponible

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):

Image non disponible
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:

 
Sélectionnez

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.

 
Sélectionnez

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 :

 
Sélectionnez

Protected Sub MDIChildNouvelle_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) 
_Handles MenuItem2.Click

   MDIFilleActive = New Form2()

   'Indique à la fenêtre fille son 'parent'.

   MDIFilleActive.MdiParent = Me

   'Affiche la fenêtre fille

   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?

 
Sélectionnez

If Not Me.ActiveMdiChild Is Nothing then    'elle existe

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:

 
Sélectionnez

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:

 
Sélectionnez

 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:

 
Sélectionnez

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.

 
Sélectionnez

dim i_form as Form ' on utilise une variable Form :formulaire 

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 ?

 
Sélectionnez

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:

 
Sélectionnez

MDIFilleActive.Affiche()

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.

 
Sélectionnez

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):

Image non disponible

Dans le menu, passer par 'Ajouter' puis 'Formulaire Windows':

Image non disponible

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.)

Image non disponible

Le code qui génère les formulaires enfants est automatiquement crée:

 
Sélectionnez

Public Class MDIParent1

Private Sub ShowNewForm(ByVal sender As Object, ByVal e As EventArgs) Handles NewToolStripMenuItem.Click, 
	_NewToolStripButton.Click, NewWindowToolStripMenuItem.Click

' Créer une nouvelle instance du formulaire enfant.

Dim ChildForm As New System.Windows.Forms.Form

' Make it a child of this MDI form before showing it.

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

'Quitter l'application

Global.System.Windows.Forms.Application.Exit()

End Sub

Private Sub CascadeToolStripMenuItem_Click(ByVal sender As Object, ByVal e As EventArgs) 
_Handles CascadeToolStripMenuItem.Click

'Positionnement des formulaires enfant

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

' Ferme tous les formulaires enfant

For Each ChildForm As Form In Me.MdiChildren

ChildForm.Close()

Next

End Sub

Private m_ChildFormNumber As Integer = 0

End Class

précédentsommairesuivant

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

  

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. 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'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.