Projet Multi-documents(Mdi) problème d'accès a un formulaire child a partir d'un

Signaler
Messages postés
75
Date d'inscription
jeudi 12 août 2004
Statut
Membre
Dernière intervention
3 décembre 2012
-
Messages postés
420
Date d'inscription
vendredi 17 novembre 2006
Statut
Membre
Dernière intervention
15 juillet 2014
-
Bonjour

J'ai un projet multi-documents qui se lance a partir

Le programme commence par un splashscreen qui se lance a partir de la MainForm(MdiParent).

Classe program

Imports System.Threading

Namespace SplashScreenThreaded
Friend NotInheritable Class Program

Private Sub New()
End Sub

''' <summary>
        ''' Le point d'entrée principal de l'application.
''' </summary>
<STAThread> _
Shared Sub Main()
Application.EnableVisualStyles()
Application.SetCompatibleTextRenderingDefault(False)
Application.Run(New MainForm())
End Sub
End Class
End Namespace


Ensuite j'ai mon formulaire Parent avec lequel je lance les formulaires child tout se passe bien :


        Public Sub NouveauCandidatToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles NouveauCandidatToolStripMenuItem.Click

            '//test si la mdi est déjà affichée
            If mdiChildAjout.Text "Ajout d'un nouveau candidat." Or Mid(mdiChildAjout.Text, 1, 22) "Modification candidat:" Then
                MsgBox("Une fenêtre pour cette fonction du programme existe déjà " & Chr(13) _
                  & "Veuillez fermer la fenêtre déjà active pour pouvoir en ouvrir un nouvelle .", vbExclamation, "Attention !")
                Exit Sub
            End If

            mdiChildAjout = New FrmNouvCandidat
            mdiChildAjout.Text = "Ajout d'un nouveau candidat."
            mdiChildAjout.MdiParent = Me
            MsgBox(mdiChildAjout.MdiParent)
            mdiChildAjout.Show()
            mdiChildAjout.TXT_NOM.Focus()
            OptionToolStripMenuItem.Enabled = False


        End Sub

        Private Sub MaximiserLaFenêtreToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MaximiserLaFenêtreToolStripMenuItem.Click
            Me.WindowState = FormWindowState.Maximized
        End Sub
        Private Sub MinimiserLaFenêtreToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MinimiserLaFenêtreToolStripMenuItem.Click
            Me.WindowState = FormWindowState.Minimized
        End Sub
        ''' <summary>
        ''' GRISER LES MENUS CONTEXTUELS QUI SONT INUTILES EN FONCTION DU CONTEXTE DE LA FENËTRE
        ''' </summary>
        ''' 


        ''' 


        ''' <remarks></remarks>
        Private Sub main_form_SizeChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.SizeChanged
            Me.MaximiserLaFenêtreToolStripMenuItem.Enabled Not (Me.WindowState FormWindowState.Maximized)
            Me.MinimiserLaFenêtreToolStripMenuItem.Enabled Not (Me.WindowState FormWindowState.Minimized)
        End Sub

        Public Sub RechercherToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RechercherToolStripMenuItem.Click
            Try
                '//test si la mdi est déjà affichée
                If mdiChildRech.Text = "Recherche de candidatures" Then
                    MsgBox("Une fenêtre pour cette fonction du programme existe déjà " & Chr(13) _
                      & "Veuillez fermer la fenêtre déjà active pour pouvoir en ouvrir un nouvelle .", vbExclamation, "Attention !")
                    Exit Sub
                End If

                mdiChildRech = New FrmRecherche
                mdiChildRech.Text = "Recherche de candidatures"
                mdiChildRech.MdiParent = Me
                mdiChildRech.Show()
                mdiChildRech.TXT_NOM.Focus()
            Catch obj_erreur As Exception
                MsgBox("Erreur dans RechercherToolStripMenuItem_Click de la FrmMain: " & obj_erreur.Message)

            End Try


        End Sub



Quand je suis dans le formulaire child je voudrais lancer le formulaire mdiChildAjout mais sans succès:

mdiChildAjout = New FrmNouvCandidat
mdiChildAjout.MdiParent = MainFrom
mdiChildAjout.Show()


J'ai une erreur sur la ligne mdiChildAjout.MdiParent = MainFrom

Erreur: inaccessible en raison de son niveau de protection.
J'ai regardé au niveau des protections (public) mais je ne vois rien .

Auriez vous une idée car la je ne vois pas.

D'avance merci

5 réponses

Messages postés
420
Date d'inscription
vendredi 17 novembre 2006
Statut
Membre
Dernière intervention
15 juillet 2014
5
Bonjour,

Il y a une chose qui n'est pas claire.

Quand vous dites "Quand je suis dans le formulaire child", vous parlez de quel formulaire enfant ? Car d'après vos explications, vous avez une fenêtre parente qui affiche deux fenêtres enfants (FrmNouvCandidat et FrmNouvCandidat) et chaque enfant ne peut être affiché qu'une seule fois.

Ce que vous voulez c'est afficher la fenêtre enfant du type "FrmNouvCandidat" depuis un clic de bouton dans la fenêtre enfant du type "FrmRecherche" ?

De plus, pourriez vous m'indiquer comment vous avez déclaré vos variables "mdiChildAjout" et "mdiChildRech" ?
Messages postés
75
Date d'inscription
jeudi 12 août 2004
Statut
Membre
Dernière intervention
3 décembre 2012

Bonjour,

Merci de ton aide.

Quand je dis:"Quand je suis dans le formulaire child" c est le mdiChildRech

J ai bien une fenêtre parent qui affiche mes fenêtres child pas de problème à ce niveau la, mais quand je suis dans ma fenêtre child mdiChildRech je ne sais pas lancer la FrmNouvCandidat car je ne sais pas renseigner la fenêtre parent:

mdiChildAjout.MdiParent = MainFrom==> fenêtre parent

Dans mon module:

Public mdiChildAjout As New FrmNouvCandidat '//Ajouter un client ou coiffeur avec photo
Public mdiChildChoixCP As New FrmChoixCP '//Choix d'un code postal lors de l'ajout d'un candidat
Public mdiChildApropos As New FrmAboutBox '//Choix d'un code postal lors de l'ajout d'un candidat
Public mdiChildRech As New FrmRecherche '//Recherche filtre candidat
Public mdiChildInfoCand As New FrmInfoCand '//Affiche les info du candidat
Public mdiChildProfil As New FrmProfil '//Affiche les différents profils(ajout,suppression)
Public mdiChildPoste As New FrmPoste '//Affiche les différents postes(ajout,suppression)

Bav,
Messages postés
420
Date d'inscription
vendredi 17 novembre 2006
Statut
Membre
Dernière intervention
15 juillet 2014
5
Essayez ceci,

Ajouter cette variable à votre module :
Public mainFormInstance As MainForm

(Si votre formulaire parent s'appelle autrement que "MainForm", remplacez "As MainForm" par son nom)

Ensuite au lancement de votre programme :
Imports System.Threading

Namespace SplashScreenThreaded
Friend NotInheritable Class Program

Private Sub New()
End Sub

''' <summary>
        ''' Le point d'entrée principal de l'application.
''' </summary>
<STAThread> _
Shared Sub Main()
Application.EnableVisualStyles()
Application.SetCompatibleTextRenderingDefault(False)
                        mainFormInstance = New MainForm()
Application.Run(mainFormInstance)
End Sub
End Class
End Namespace


Et enfin lorsque vous tentez d'ouvrir mdiChildAjout depuis mdiChildRech :
mdiChildAjout = New FrmNouvCandidat
mdiChildAjout.MdiParent = mainFormInstance
mdiChildAjout.Show()


L'explication étant qu'écrire :
mdiChildAjout.MdiParent = MainFrom

n'a pas de sens car "MainForm" est une classe et pas une instance de la classe.

Donc en déclarant mainFormInstance dans votre module et en affectant une instance de la classe MainForm à cette variable, vous pourrez accéder à votre formulaire parent n'importe ou dans votre programme.
Messages postés
420
Date d'inscription
vendredi 17 novembre 2006
Statut
Membre
Dernière intervention
15 juillet 2014
5
Petit rectification, je n'avais pas fait attention au fait que vous faite un New au moment de la déclaration dans le module.

Il faudra donc faire les adaptations suivantes :
1) Dans le module :
Public mainFormInstance As MainForm
Public mdiChildAjout As FrmNouvCandidat '//Ajouter un client ou coiffeur avec photo 
Public mdiChildChoixCP As FrmChoixCP '//Choix d'un code postal lors de l'ajout d'un candidat 
Public mdiChildApropos As FrmAboutBox '//Choix d'un code postal lors de l'ajout d'un candidat 
Public mdiChildRech As FrmRecherche '//Recherche filtre candidat 
Public mdiChildInfoCand As FrmInfoCand '//Affiche les info du candidat 
Public mdiChildProfil As FrmProfil '//Affiche les différents profils(ajout,suppression) 
Public mdiChildPoste As FrmPoste '//Affiche les différents postes(ajout,suppression) 

On enlève les "New"

2) Au lancement du programme :
Imports System.Threading

Namespace SplashScreenThreaded
Friend NotInheritable Class Program

Private Sub New()
End Sub

''' <summary>
        ''' Le point d'entrée principal de l'application.
''' </summary>
<STAThread> _
Shared Sub Main()
Application.EnableVisualStyles()
Application.SetCompatibleTextRenderingDefault(False)
                        mainFormInstance = New MainForm()
                        mdiChildAjout = New FrmNouvCandidat() 
                        mdiChildChoixCP = New FrmChoixCP() 
                        mdiChildApropos = New FrmAboutBox() 
                        mdiChildRech = New FrmRecherche() 
                        mdiChildInfoCand = New FrmInfoCand() 
                        mdiChildProfil = New FrmProfil() 
                        mdiChildPoste = New FrmPoste() 
Application.Run(mainFormInstance)
End Sub
End Class
End Namespace

On crée les instances après
Application.SetCompatibleTextRenderingDefault(False)

Sinon il y a une erreur au lancement du programme
Messages postés
420
Date d'inscription
vendredi 17 novembre 2006
Statut
Membre
Dernière intervention
15 juillet 2014
5
Et pour la petite histoire, pour les gens qui passeraient sur ce post et se poseraient la question "si MainForm n'est pas une instance, alors pourquoi
mdiChildAjout.MdiParent = MainForm
ne génère pas d'erreur de compilation ?" voici la petite explication.

Il y a une particularité en VB.NET (qui, il me semble, n'existe pas en C#) qui fait que lorsqu'on crée un formulaire, par exemple "Toto", dans une application, par exemple "MonApplication", une variable d'instance de cette classe est automatiquement ajouté au projet et accessible via la proriété :
Global.MonApplication.My.Forms.Toto


Et une autre particularité qui horripile certains développeurs est que cette propriété peut être appelée de toutes les façons suivantes :
Global.MonApplication.My.Forms.Toto

MonApplication.My.Forms.Toto

My.Forms.Toto

et malheureusement
Toto


D'ou une horrible confusion entre la classe et la propriété.

Par exemple, dans votre cas neotof, si vous aviez écrit:
Namespace SplashScreenThreaded
Friend NotInheritable Class Program

Private Sub New()
End Sub

''' <summary>
        ''' Le point d'entrée principal de l'application.
''' </summary>
<STAThread> _
Shared Sub Main()
Application.EnableVisualStyles()
Application.SetCompatibleTextRenderingDefault(False)                      
Application.Run(MainForm)
End Sub
End Class
End Namespace

qui est en faite
Application.Run(Global.NomDeApplication.My.Forms.MainForm)

à la place de
Application.Run(New MainForm())

Vous auriez pu faire, normalement :
mdiChildAjout = New FrmNouvCandidat
mdiChildAjout.MdiParent = MainForm
mdiChildAjout.Show()


Car dans ce cas, au lancement de l'application, une nouvelle instance de la classe "MainForm" aurait bien été affecté à la propriété "My.Forms.MainForm" puis affiché à l'écran et du coup rendue accessible au autres formulaires.