OVH Cloud OVH Cloud

Evènement Closing

4 réponses
Avatar
Stephane TUET
Bonjour à tous

J'ai dans mon application MDI mis en place un système qui me permet d'avoir
des relations entre les fenêtres enfants et leur fenêtre parent. Une fenêtre
contact par exemple va posséder un attribut FenetreParent de type Form qui
peut être ma fenêtre de gestion des clients ou ma fenêtre de gestion des
fournisseurs. Ceci dans l'objectif de détecter l'évènement Closing de la
fenêtre parent, pour pouvoir fermer les fenêtres enfants en même temps (si
on ferme la fenêtre client alors qu'un de ses contacts est ouvert, la
fenêtre contact se ferme également). Je me suis donc basé tout naturellement
sur la détection de l'évènement Closing de FenetreParent dans mes fenêtres
enfants.

Le problème c'est que l'évènement Closing est tout d'abord exécuté dans la
fenêtre parent et ensuite seulement dans la fenêtre enfant, ce qui fait que
si j'ai eu des modifications dans la fenêtre contact, la fenêtre parent ne
détecte pas ces changements et est incapable des les enregistrer...

Donc ma première question est (mais j'en doute fortement) est-il possible
d'exécuter d'abord l'évènement dans les fenêtres enfants avant celui de la
fenêtre parent ?

Une autre solution consiterai à créer soit même un évènement
DemandeDeFermeture qui serait lancé par la fenêtre parent au début du
Closing, mais comme je l'ai dit pour l'exemple de ma fenêtre contact, sa
fenêtre parent est de type Form puisqu'il peut s'agir d'une fenêtre client
ou d'une fenêtre fournisseur, donc pas d'accès à cette évènement...

Quelqu'un aurait-il une solution à ce problème ?

Merci d'avance

Stéphane

4 réponses

Avatar
Zoury
Salut Stéphane ! :O)

J'ai dans mon application MDI mis en place un système qui me permet
d'avoir des relations entre les fenêtres enfants et leur fenêtre parent.



... il en existe déjà un.. peux-tu nous donner plus de précision ?


Une fenêtre contact par exemple va posséder un attribut FenetreParent de
type Form



Regarde du côté de la propriété MDIParent de la classe Form.


Ceci dans l'objectif de détecter l'évènement Closing de la fenêtre parent,
pour pouvoir fermer les fenêtres enfants en même temps



Si tu ouvres correctement tes fenêtres enfants, c'est qui devrait déjà se
produire.

Voici un exemple avec un formulaire MDI parent (Form1) et un formulaire MDI
enfant (Form2)

Ex :
'***
Public Class Form1
Inherits System.Windows.Forms.Form

#Region " Code généré par le Concepteur Windows Form "

Public Sub New()
MyBase.New()

'Cet appel est requis par le Concepteur Windows Form.
InitializeComponent()

'Ajoutez une initialisation quelconque après l'appel
InitializeComponent()

End Sub

'La méthode substituée Dispose du formulaire pour nettoyer la liste des
composants.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub

'Requis par le Concepteur Windows Form
Private components As System.ComponentModel.IContainer

'REMARQUE : la procédure suivante est requise par le Concepteur Windows
Form
'Elle peut être modifiée en utilisant le Concepteur Windows Form.
'Ne la modifiez pas en utilisant l'éditeur de code.
<System.Diagnostics.DebuggerStepThrough()> Private Sub
InitializeComponent()
'
'Form1
'
Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
Me.ClientSize = New System.Drawing.Size(292, 266)
Me.IsMdiContainer = True
Me.Name = "Form1"
Me.Text = "Form1"

End Sub

#End Region

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load

Dim frm As New Form2
frm.MdiParent = Me
frm.Show()

End Sub

Private Sub Form1_Closing(ByVal sender As Object, ByVal e As
System.ComponentModel.CancelEventArgs) Handles MyBase.Closing
Console.WriteLine("Form1")
End Sub

End Class
'***
Public Class Form2
Inherits System.Windows.Forms.Form

#Region " Code généré par le Concepteur Windows Form "

Public Sub New()
MyBase.New()

'Cet appel est requis par le Concepteur Windows Form.
InitializeComponent()

'Ajoutez une initialisation quelconque après l'appel
InitializeComponent()

End Sub

'La méthode substituée Dispose du formulaire pour nettoyer la liste des
composants.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub

'Requis par le Concepteur Windows Form
Private components As System.ComponentModel.IContainer

'REMARQUE : la procédure suivante est requise par le Concepteur Windows
Form
'Elle peut être modifiée en utilisant le Concepteur Windows Form.
'Ne la modifiez pas en utilisant l'éditeur de code.
<System.Diagnostics.DebuggerStepThrough()> Private Sub
InitializeComponent()
components = New System.ComponentModel.Container()
Me.Text = "Form2"
End Sub

#End Region

Private Sub Form2_Closing(ByVal sender As Object, ByVal e As
System.ComponentModel.CancelEventArgs) Handles MyBase.Closing
Console.WriteLine("Form2")
End Sub

End Class
'***

Si tu exécutes ce programme, Form1 s'ouvre en tant que conteneur MDI et
Form2 s'ouvre en tant que fenêtre enfant *dans* Form1. Maintenant, si tu
fermes le formulaire parent (Form1), tu devais voir ces deux lignes s'ajouté
à ta fenêtre de sortie :
Fermeture de Form2
Fermeture de Form1

Signifiant que l'événement Closing de la fenêtre enfant s'est bel et bien
déclenché avant celui de la fenêtre parent.


--
Cordialement
Yanick
MVP pour Visual Basic
Avatar
Stephane TUET
Merci pour ta réponse Zoury.

Cependant le système que tu proposes est bien celui que j'utilise pour la
gestion de mes fenêtres : une fenêtre MDI container dans laquelle s'ouvre
des fenêtres enfants en leur affectant la propriété MDIParent. Ca c'est pour
le 1er niveau.

Cette fenêtre MDI Container est la fenêtre principale de mon application, la
fenêtre enfant est la fenêtre de gestion d'un client. Jusque là tu as raison
tout fonctionne parfaitement. Maintenant si la fenêtre MDIChild (la fênetre
enfant, donc la fenêtre de gestion d'un client) ouvre une autre fenêtre pour
un contact par exemple, cette fenêtre est également définie enfant de la
fenêtre MDI Container, mais doit également être définie enfant de la fenêtre
MDIChild (la fenêtre client), ce que je réalise à l'aide de mon attribut
FenetreParent.

C'est à ce niveau que, quand je ferme la fenêtre Client, je voudrais que la
fenêtre Contact se ferme en premier.

Pour résumé, mon problème est de créer des relations Enfant/Parent entre des
feuilles MDIChild, avec l'évènement Closing de la fenêtre "Enfant" qui
intervient avant le Closing de la fenêtre "Parent" (mais toutes deux
MDIChild).

J'espère avoir été plus clair et merci pour ton aide

Steph

"Zoury" <yanick_lefebvre at hotmail dot com> a écrit dans le message de
news:
Salut Stéphane ! :O)

J'ai dans mon application MDI mis en place un système qui me permet
d'avoir des relations entre les fenêtres enfants et leur fenêtre parent.



... il en existe déjà un.. peux-tu nous donner plus de précision ?


Une fenêtre contact par exemple va posséder un attribut FenetreParent de
type Form



Regarde du côté de la propriété MDIParent de la classe Form.


Ceci dans l'objectif de détecter l'évènement Closing de la fenêtre
parent, pour pouvoir fermer les fenêtres enfants en même temps



Si tu ouvres correctement tes fenêtres enfants, c'est qui devrait déjà se
produire.

Voici un exemple avec un formulaire MDI parent (Form1) et un formulaire
MDI enfant (Form2)

Ex :
'***
Public Class Form1
Inherits System.Windows.Forms.Form

#Region " Code généré par le Concepteur Windows Form "

Public Sub New()
MyBase.New()

'Cet appel est requis par le Concepteur Windows Form.
InitializeComponent()

'Ajoutez une initialisation quelconque après l'appel
InitializeComponent()

End Sub

'La méthode substituée Dispose du formulaire pour nettoyer la liste des
composants.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub

'Requis par le Concepteur Windows Form
Private components As System.ComponentModel.IContainer

'REMARQUE : la procédure suivante est requise par le Concepteur Windows
Form
'Elle peut être modifiée en utilisant le Concepteur Windows Form.
'Ne la modifiez pas en utilisant l'éditeur de code.
<System.Diagnostics.DebuggerStepThrough()> Private Sub
InitializeComponent()
'
'Form1
'
Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
Me.ClientSize = New System.Drawing.Size(292, 266)
Me.IsMdiContainer = True
Me.Name = "Form1"
Me.Text = "Form1"

End Sub

#End Region

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load

Dim frm As New Form2
frm.MdiParent = Me
frm.Show()

End Sub

Private Sub Form1_Closing(ByVal sender As Object, ByVal e As
System.ComponentModel.CancelEventArgs) Handles MyBase.Closing
Console.WriteLine("Form1")
End Sub

End Class
'***
Public Class Form2
Inherits System.Windows.Forms.Form

#Region " Code généré par le Concepteur Windows Form "

Public Sub New()
MyBase.New()

'Cet appel est requis par le Concepteur Windows Form.
InitializeComponent()

'Ajoutez une initialisation quelconque après l'appel
InitializeComponent()

End Sub

'La méthode substituée Dispose du formulaire pour nettoyer la liste des
composants.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub

'Requis par le Concepteur Windows Form
Private components As System.ComponentModel.IContainer

'REMARQUE : la procédure suivante est requise par le Concepteur Windows
Form
'Elle peut être modifiée en utilisant le Concepteur Windows Form.
'Ne la modifiez pas en utilisant l'éditeur de code.
<System.Diagnostics.DebuggerStepThrough()> Private Sub
InitializeComponent()
components = New System.ComponentModel.Container()
Me.Text = "Form2"
End Sub

#End Region

Private Sub Form2_Closing(ByVal sender As Object, ByVal e As
System.ComponentModel.CancelEventArgs) Handles MyBase.Closing
Console.WriteLine("Form2")
End Sub

End Class
'***

Si tu exécutes ce programme, Form1 s'ouvre en tant que conteneur MDI et
Form2 s'ouvre en tant que fenêtre enfant *dans* Form1. Maintenant, si tu
fermes le formulaire parent (Form1), tu devais voir ces deux lignes
s'ajouté à ta fenêtre de sortie :
Fermeture de Form2
Fermeture de Form1

Signifiant que l'événement Closing de la fenêtre enfant s'est bel et bien
déclenché avant celui de la fenêtre parent.


--
Cordialement
Yanick
MVP pour Visual Basic



Avatar
David Bouchard
Salut, si tu appele le close de tes fenêtres enfant à la place à partir de
ta fenêtre parent, tu pourrais régler ton problème il me semble. Donc, quand
ta fenetre parent se fermerait avec l'évènement Closing, tu ferais une
itération sur tes forms enfants en appelant leurs fontions close.
Évidemment, il faut que tu gère ta collection de form enfant.
Private _Collection_Form_Enfants As new ArrayList

Private Sub Form1_Closing(ByVal sender As Object, ByVal e As
System.ComponentModel.CancelEventArgs) Handles MyBase.Closing

For Each f As Form In _Collection_Form_Enfants

f.Close()

Next

End Sub




"Stephane TUET" a écrit dans le message de news:

Merci pour ta réponse Zoury.

Cependant le système que tu proposes est bien celui que j'utilise pour la
gestion de mes fenêtres : une fenêtre MDI container dans laquelle s'ouvre
des fenêtres enfants en leur affectant la propriété MDIParent. Ca c'est
pour
le 1er niveau.

Cette fenêtre MDI Container est la fenêtre principale de mon application,
la
fenêtre enfant est la fenêtre de gestion d'un client. Jusque là tu as
raison
tout fonctionne parfaitement. Maintenant si la fenêtre MDIChild (la
fênetre
enfant, donc la fenêtre de gestion d'un client) ouvre une autre fenêtre
pour
un contact par exemple, cette fenêtre est également définie enfant de la
fenêtre MDI Container, mais doit également être définie enfant de la
fenêtre
MDIChild (la fenêtre client), ce que je réalise à l'aide de mon attribut
FenetreParent.

C'est à ce niveau que, quand je ferme la fenêtre Client, je voudrais que
la
fenêtre Contact se ferme en premier.

Pour résumé, mon problème est de créer des relations Enfant/Parent entre
des
feuilles MDIChild, avec l'évènement Closing de la fenêtre "Enfant" qui
intervient avant le Closing de la fenêtre "Parent" (mais toutes deux
MDIChild).

J'espère avoir été plus clair et merci pour ton aide

Steph

"Zoury" <yanick_lefebvre at hotmail dot com> a écrit dans le message de
news:
Salut Stéphane ! :O)

J'ai dans mon application MDI mis en place un système qui me permet
d'avoir des relations entre les fenêtres enfants et leur fenêtre parent.



... il en existe déjà un.. peux-tu nous donner plus de précision ?


Une fenêtre contact par exemple va posséder un attribut FenetreParent de
type Form



Regarde du côté de la propriété MDIParent de la classe Form.


Ceci dans l'objectif de détecter l'évènement Closing de la fenêtre
parent, pour pouvoir fermer les fenêtres enfants en même temps



Si tu ouvres correctement tes fenêtres enfants, c'est qui devrait déjà se
produire.

Voici un exemple avec un formulaire MDI parent (Form1) et un formulaire
MDI enfant (Form2)

Ex :
'***
Public Class Form1
Inherits System.Windows.Forms.Form

#Region " Code généré par le Concepteur Windows Form "

Public Sub New()
MyBase.New()

'Cet appel est requis par le Concepteur Windows Form.
InitializeComponent()

'Ajoutez une initialisation quelconque après l'appel
InitializeComponent()

End Sub

'La méthode substituée Dispose du formulaire pour nettoyer la liste
des composants.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub

'Requis par le Concepteur Windows Form
Private components As System.ComponentModel.IContainer

'REMARQUE : la procédure suivante est requise par le Concepteur
Windows Form
'Elle peut être modifiée en utilisant le Concepteur Windows Form.
'Ne la modifiez pas en utilisant l'éditeur de code.
<System.Diagnostics.DebuggerStepThrough()> Private Sub
InitializeComponent()
'
'Form1
'
Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
Me.ClientSize = New System.Drawing.Size(292, 266)
Me.IsMdiContainer = True
Me.Name = "Form1"
Me.Text = "Form1"

End Sub

#End Region

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load

Dim frm As New Form2
frm.MdiParent = Me
frm.Show()

End Sub

Private Sub Form1_Closing(ByVal sender As Object, ByVal e As
System.ComponentModel.CancelEventArgs) Handles MyBase.Closing
Console.WriteLine("Form1")
End Sub

End Class
'***
Public Class Form2
Inherits System.Windows.Forms.Form

#Region " Code généré par le Concepteur Windows Form "

Public Sub New()
MyBase.New()

'Cet appel est requis par le Concepteur Windows Form.
InitializeComponent()

'Ajoutez une initialisation quelconque après l'appel
InitializeComponent()

End Sub

'La méthode substituée Dispose du formulaire pour nettoyer la liste
des composants.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub

'Requis par le Concepteur Windows Form
Private components As System.ComponentModel.IContainer

'REMARQUE : la procédure suivante est requise par le Concepteur
Windows Form
'Elle peut être modifiée en utilisant le Concepteur Windows Form.
'Ne la modifiez pas en utilisant l'éditeur de code.
<System.Diagnostics.DebuggerStepThrough()> Private Sub
InitializeComponent()
components = New System.ComponentModel.Container()
Me.Text = "Form2"
End Sub

#End Region

Private Sub Form2_Closing(ByVal sender As Object, ByVal e As
System.ComponentModel.CancelEventArgs) Handles MyBase.Closing
Console.WriteLine("Form2")
End Sub

End Class
'***

Si tu exécutes ce programme, Form1 s'ouvre en tant que conteneur MDI et
Form2 s'ouvre en tant que fenêtre enfant *dans* Form1. Maintenant, si tu
fermes le formulaire parent (Form1), tu devais voir ces deux lignes
s'ajouté à ta fenêtre de sortie :
Fermeture de Form2
Fermeture de Form1

Signifiant que l'événement Closing de la fenêtre enfant s'est bel et bien
déclenché avant celui de la fenêtre parent.


--
Cordialement
Yanick
MVP pour Visual Basic







Avatar
Stephane TUET
Salut

En effet, je crois que c'est la seule solution possible à mon problème. Je
pense que c'est ce que je vais faire. Merci de ton aide !

Steph


"David Bouchard" a écrit dans le message de news:
%
Salut, si tu appele le close de tes fenêtres enfant à la place à partir de
ta fenêtre parent, tu pourrais régler ton problème il me semble. Donc,
quand ta fenetre parent se fermerait avec l'évènement Closing, tu ferais
une itération sur tes forms enfants en appelant leurs fontions close.
Évidemment, il faut que tu gère ta collection de form enfant.
Private _Collection_Form_Enfants As new ArrayList

Private Sub Form1_Closing(ByVal sender As Object, ByVal e As
System.ComponentModel.CancelEventArgs) Handles MyBase.Closing

For Each f As Form In _Collection_Form_Enfants

f.Close()

Next

End Sub




"Stephane TUET" a écrit dans le message de news:

Merci pour ta réponse Zoury.

Cependant le système que tu proposes est bien celui que j'utilise pour la
gestion de mes fenêtres : une fenêtre MDI container dans laquelle s'ouvre
des fenêtres enfants en leur affectant la propriété MDIParent. Ca c'est
pour
le 1er niveau.

Cette fenêtre MDI Container est la fenêtre principale de mon application,
la
fenêtre enfant est la fenêtre de gestion d'un client. Jusque là tu as
raison
tout fonctionne parfaitement. Maintenant si la fenêtre MDIChild (la
fênetre
enfant, donc la fenêtre de gestion d'un client) ouvre une autre fenêtre
pour
un contact par exemple, cette fenêtre est également définie enfant de la
fenêtre MDI Container, mais doit également être définie enfant de la
fenêtre
MDIChild (la fenêtre client), ce que je réalise à l'aide de mon attribut
FenetreParent.

C'est à ce niveau que, quand je ferme la fenêtre Client, je voudrais que
la
fenêtre Contact se ferme en premier.

Pour résumé, mon problème est de créer des relations Enfant/Parent entre
des
feuilles MDIChild, avec l'évènement Closing de la fenêtre "Enfant" qui
intervient avant le Closing de la fenêtre "Parent" (mais toutes deux
MDIChild).

J'espère avoir été plus clair et merci pour ton aide

Steph

"Zoury" <yanick_lefebvre at hotmail dot com> a écrit dans le message de
news:
Salut Stéphane ! :O)

J'ai dans mon application MDI mis en place un système qui me permet
d'avoir des relations entre les fenêtres enfants et leur fenêtre
parent.



... il en existe déjà un.. peux-tu nous donner plus de précision ?


Une fenêtre contact par exemple va posséder un attribut FenetreParent
de type Form



Regarde du côté de la propriété MDIParent de la classe Form.


Ceci dans l'objectif de détecter l'évènement Closing de la fenêtre
parent, pour pouvoir fermer les fenêtres enfants en même temps



Si tu ouvres correctement tes fenêtres enfants, c'est qui devrait déjà
se produire.

Voici un exemple avec un formulaire MDI parent (Form1) et un formulaire
MDI enfant (Form2)

Ex :
'***
Public Class Form1
Inherits System.Windows.Forms.Form

#Region " Code généré par le Concepteur Windows Form "

Public Sub New()
MyBase.New()

'Cet appel est requis par le Concepteur Windows Form.
InitializeComponent()

'Ajoutez une initialisation quelconque après l'appel
InitializeComponent()

End Sub

'La méthode substituée Dispose du formulaire pour nettoyer la liste
des composants.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub

'Requis par le Concepteur Windows Form
Private components As System.ComponentModel.IContainer

'REMARQUE : la procédure suivante est requise par le Concepteur
Windows Form
'Elle peut être modifiée en utilisant le Concepteur Windows Form.
'Ne la modifiez pas en utilisant l'éditeur de code.
<System.Diagnostics.DebuggerStepThrough()> Private Sub
InitializeComponent()
'
'Form1
'
Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
Me.ClientSize = New System.Drawing.Size(292, 266)
Me.IsMdiContainer = True
Me.Name = "Form1"
Me.Text = "Form1"

End Sub

#End Region

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load

Dim frm As New Form2
frm.MdiParent = Me
frm.Show()

End Sub

Private Sub Form1_Closing(ByVal sender As Object, ByVal e As
System.ComponentModel.CancelEventArgs) Handles MyBase.Closing
Console.WriteLine("Form1")
End Sub

End Class
'***
Public Class Form2
Inherits System.Windows.Forms.Form

#Region " Code généré par le Concepteur Windows Form "

Public Sub New()
MyBase.New()

'Cet appel est requis par le Concepteur Windows Form.
InitializeComponent()

'Ajoutez une initialisation quelconque après l'appel
InitializeComponent()

End Sub

'La méthode substituée Dispose du formulaire pour nettoyer la liste
des composants.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub

'Requis par le Concepteur Windows Form
Private components As System.ComponentModel.IContainer

'REMARQUE : la procédure suivante est requise par le Concepteur
Windows Form
'Elle peut être modifiée en utilisant le Concepteur Windows Form.
'Ne la modifiez pas en utilisant l'éditeur de code.
<System.Diagnostics.DebuggerStepThrough()> Private Sub
InitializeComponent()
components = New System.ComponentModel.Container()
Me.Text = "Form2"
End Sub

#End Region

Private Sub Form2_Closing(ByVal sender As Object, ByVal e As
System.ComponentModel.CancelEventArgs) Handles MyBase.Closing
Console.WriteLine("Form2")
End Sub

End Class
'***

Si tu exécutes ce programme, Form1 s'ouvre en tant que conteneur MDI et
Form2 s'ouvre en tant que fenêtre enfant *dans* Form1. Maintenant, si tu
fermes le formulaire parent (Form1), tu devais voir ces deux lignes
s'ajouté à ta fenêtre de sortie :
Fermeture de Form2
Fermeture de Form1

Signifiant que l'événement Closing de la fenêtre enfant s'est bel et
bien déclenché avant celui de la fenêtre parent.


--
Cordialement
Yanick
MVP pour Visual Basic