Site:  Cours VB.net  
4.2 Bis Faire communiquer 2 formulaires .

Rappel:Formulaire=fenêtre

Comment faire communiquer 2 formulaires?+++

A- Comment à partir d'un formulaire consulter un objet d'un autre formulaire?

B- Comment à partir du second formulaire connaître le formulaire propriétaire?

C- Les formulaires ouverts en VB 2005

 

Cette question est fréquemment posée et créée beaucoup de problèmes!!

Soit Form1 et Form2.

A- Comment à partir du premier formulaire  consulter un objet du second formulaire?

 

1-En VB 2003 (en VB 2005) 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 saisi un texte dans le textbox2 et quitte formsecondaire. Comment Form1 peut-il récupérer TextBox2.text et l'afficher dans un label1

 

 Class Form1

Contient Button1 "Créer Form2"

Contient Label1

 

 

 Class Form2  instance: formsecondaire

Contient TextBox2

Contient Button2 "Quitter"

 

 

1-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 ()    '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).

Dim formSecondaireAs New Form2()

formSecondaire.ShowDialog()

label1.Text=formSecondaire.TextBox2.Text

formSecondaire.Close()

 

Une fois que le texte à été récupéré, on faire 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()           '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.

 

 

2 - 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

On peut l'ouvrir  n'importe ou!!

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

 

3 -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 'Bouton quitter

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

Me.Close()

End Sub

End Class

 

Dans Form1

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:

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

4 -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     'Variable Public 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...

Mais c'est simple et cela marche bien.

 

 

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

 

 

B- 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)
'affichage modal de la form2

Dans Form2:   

 Private FormProp As Form1
    Public Sub New(ByVal NomForm As Form1)
        MyBase.New()
        FormProp = NomForm
        'This call is required by the Windows Form Designer.
        InitializeComponent()

        'Add any initialization after the InitializeComponent() call

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

FormProp.MaRoutine()

 

L'inconvénient de toutes ces méthodes est qu'il faut connaître la classe du formulaire propriétaire (Form1 ici).

 
C- Les formulaires ouverts en 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?

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   

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