How can I make second-level child forms prompt on close?
The problem: A dialog's FormClosing() event is raised if it's a child, ie it's Owner property is set to the parent form, but NOT if it's a child-of-a-child. So closing the main form does not call the closing event on any grandchildren dialogs.
The Details: A dialog prompts to "Save Changes?", with YesNoCancel buttons, in the FormClosing() event. Clicking Cancel keeps the dialog open, ie cancel closing.
Private Sub Dialog_FormClosing(...) Handles Me.FormClosing
开发者_开发技巧 If MessageBox.Show("Save Changes?", YesNoCancel) = No Then
e.Cancel = True
End If
End Sub
So instantiating a new dialog, with its Owner property set...
// called from the main form
Dim dlg As New Dialog
dlg.Owner = Me
dlg.Show()
... has the benefit that the dialog will prompt to save if the user tries closing the owner/parent. Clicking Cancel will keep the dialog open, and it's owner as well.
But if that same dialog was shown from a child of a parent (also with it's owner property set), and not from a parent:
// called from another child
Dim dlg As New Dialog
dlg.Owner = Me
dlg.Show()
Then the FormClosing() event on the child does not raise, if the top-most parent is closed.
Is this a know design limitation in the framework? Is there anything I should consider before I start hacking a nasty solution for this?
Thanks for any replies.
Yes. Part of the problem is that you talk about them as dialogs but don't actually use the ShowDialog() method to display them. That would make it impossible for the user to close the main form while a dialog is displayed. The message loop terminates when the main form is closed, the remaining forms will be disposed without going through the normal shutdown sequence.
One solution is to pro-actively close the forms yourself when the main form closes. This worked well:
Private Sub Form1_FormClosing(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles MyBase.FormClosing
For frm As Integer = Application.OpenForms.Count - 1 To 1 Step -1
Application.OpenForms(frm).Close()
If Application.OpenForms.Count - 1 = frm Then
e.Cancel = True
Exit For
End If
Next
End Sub
You probably should pay attention to e.CloseReason so you don't block a Windows shutdown.
精彩评论