Closing parent form when child form also closes - vb.net

Aside from my main form I have another form, frmAddFixture, which can open frmAddReport.
I'm simply trying to close frmAddFixture when "No" is selected from the msgbox, which also closes (successfully) Me (frmAddReport). If "Yes" is selected frmAddFixture should stay open, which it does. But I can't get it to close for "No". I've tried adding my own handler in to detect when frmAddReport is closing, but I couldn't get that working.
frmAddReport Code (run after a "Submit" button has been clicked):
Private Sub showMsg()
Select Case MsgBox("Do you want to add another player report for this fixture?", MsgBoxStyle.Question + MsgBoxStyle.YesNo, "Add further reports")
Case MsgBoxResult.Yes
isNewFixture = False
Me.Close()
Case MsgBoxResult.No
isNewFixture = True
Me.Close()
''Close frmAddFixture
'frmAddFixture.Dispose()
'frmAddFixture.Close()
'frmAddFixture.Hide()
End Select
End Sub
Attempted:
Private Sub frmAddReport_FormClosed(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.FormClosed
frmAddFixture.Dispose()
End Sub

Here is what I think you are trying to do.
Let's ignore the message box for a moment and say that we have two forms : Form1 and Form2. We want that as soon as Form2 is colsed, Form1 will be disposed (closed) as well. I'ts pretty simeple :
Public Class Form2
' Occurs when Form2 is closed (note the event handler).
Private Sub Form2_FormClosed(sender As Object, e As EventArgs) Handles MyBase.FormClosed
Form1.Dispose()
End Sub
End Class

Related

Terminate program when Close button is Clicked after Prompt - Visual Basic

I have two forms in my WindowsFormApplication named as Form1 and Form2. The idea is when the Program is being closed, it shows up a Dialog Box to confirm it.
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Form2.Show()
Me.Close()
End Sub
Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
MessageBox.Show("You are About to cancel the Setup.","Cancel Setup?",
MessageBoxButtons.OK,
MessageBoxIcon.Exclamation,
MessageBoxDefaultButton.Button1)
End Sub
End Class
Until here, my code worked fine but the problem is when I click Button1, the Message Box appears to confirm the closure of Form1.
I don't want this to happen so then I tried changing Me.Close() to Me.Hide. I was successful for preventing the message box to appear but then I got another Problem. As the Form hides, it stays active in the background and I also don't want this to happen.
Another thing I added in Form1_FormClosing is Me. Close and Form2.Close. This enables to close both the forms once the program's active Form is being closed. But Again, there's a problem. As soon as I click the close button, the Message Boxes fill up the screen and not listening to my Command. Anyone got a solution for this?
So..
If the user clicks close in Form1, then the program should terminate with no messagebox.
If the user clocks close in Form2, Form3 or Form4, the program would Terminate when the user clicks Yes in the MessageBox or else nothing would get affected (Especially the Data).
The way this works is when user clicks Close in Form1, the program terminates with no MessageBox and if the user clicks Close in other Forms, A MessageBox would appear asking whether you are sure to close the Program. If the user clicks Yes, the program will Terminate because the DialogResult is Yes and Form1.Closing Cancel goes to False and Closes Form1(As Closure type was set as First Form Closes in Program Properties, this will terminate the program) Else the Form1.Closing Cancel goes to True which will prevent the current Form from closing and losing any Data.
This code goes to Form1:
Imports System.ComponentModel
Public Class Form1
Friend closeProgramAlreadyRequested As Boolean = False
Private Sub Form1_Closing(sender As Object, e As CancelEventArgs) Handles Me.Closing
closeProgramAlreadyRequested = False
End Sub
End Class
This code goes to Form2 & applies to other Forms as well but except for Form1:
Imports System.ComponentModel
Public Class Form2
Private Sub Form2_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
If Form1.closeProgramAlreadyRequested = False Then
Dim result As DialogResult = MessageBox.Show("You are About to cancel the Setup.", "Cancel Setup?", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1)
If result = DialogResult.No Then
e.Cancel = True
Else
e.Cancel = False
Form1.Close()
End If
End If
End Sub
End Class

Form2 won't close and if I close it form1 will close as well. vb.net

So I made this game in vb.net, and when you run it, it will ask you for a name, that's form2. The thing is, when you put a name, form2 will not close/disappear, and if you close it the whole game will close.
This is the code for form2:
Public Class Form2
Public Shared myMoney As Long
Public Shared welcome As String
Private Sub PositronButton1_Click(sender As Object, e As EventArgs) Handles PositronButton1.Click
Form1.welcome = txtName.Text
Form1.lblWelkom.Text = "Welcome," & " " & Form1.welcome
MsgBox("Welcome," & " " & Form1.welcome & "." & "You recieved 500 money.")
Form1.myMoney = 500
Form1.lblMoney.Text = Form1.myMoney
Form1.Show()
End Sub
Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.TopMost = True
End Sub
End Class
It seems you have wrong settings in your project.
Go to "Project", "Settings" and then have a look after "Shutdown mode".
Yours is probably set to "When last form closes". But you have to set "start form".
Also do not use Form1.Show because this is wrong, create an instance of it, then call it.
Dim frm As New Form1
frm.Show()
Also use ShowDialog for showing the Form2, it returns a DialogResult, and if it is "OK", you can close the form.
Firstly, instead of setting Me.TopMost on the load event, you should call Form2.Focus() when you first open the Form in your Form1 code.
Secondly I am not sure how you are opening Form2, I assume you are using ShowDialog() In that case, in order to close Form2, you should call Me.DialogResult = DialogResult.OK
Hope it Helps

Check if any dialog is open

Does anybody see my mistake here?
I am unable to recognize if a form is shown as a dialog in my app.
Public Class Form1
Private m As Form2
Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As EventArgs) Handles Timer1.Tick
Me.Text = DateTime.Now.ToLongTimeString & " " & IsAnyDialogShown()
End Sub
Public Function IsAnyDialogShown() As Boolean
For Each f As Form In Me.OwnedForms
If f.Owner Is Me Then
Return True
End If
Next
End Function
Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click
m = New Form2
m.ShowDialog()
End Sub
End Class
What you are looking is for the property modal.
Check if the form's modal property is true (that is meaning that the form is showed with ShowDialog)
For Each f As Form In Me.OwnedForms
If f.Modal=True Then
'your code here
End If
Next
Now for your mistake (I haven't visual studio to try it right now) but your IsAnyDialogShown(), it seems that it returns always true :
For Each f As Form In Me.OwnedForms ' (So f belongs to Me)
If f.Owner Is Me Then 'f.Owner is always me because you are seaching in forms that have as owner the Me form
Return True
End If
Next
Hope I helped a little.
Tell me if I can do something more
So after your comments.
Try this:
For Each frm as Form In Application.OpenForms
If frm.Modal=True Then
'do something
'Actually you should have only one form because only one can be in modal state
end if
Next
You need to check Visible property of the form, which is the boolean.
If it is true, then form is shown, else it's hidden.
That's just doing forms owned by Me. Nothing to do with whether they are dialog forms.
ie.e it will pick up normal forms.
Also if you want this to work as expected , you should use the overload where you pass the owner.
as in m.ShowDialog(Me);
Not something I've ever done but if Owner isn't me in Me.OwnedForms I want my money back.

VB.NET ShowDialog Form not Ending

I converted this app from VB6. I have 2 forms. Form1 instantiates Form2 via a Menu Item.
I am having trouble getting Form2 to end when clicking close (X). If Form2 is 'idle' it closes fine; but if I am in a loop processing anything all the events fire, but it continues processing in Form2. I've tried messing with Dispose, Close, Application.Exit, Application.ExitThread. My last attempt was creating my own event to fire back to Form1 and dispose Form2 -- and it hits it but Form2 is still running. What is the deal? BTW if I use just Show vs ShowDialog -- Form2 just blinks and disappears.
Form1 does this
Dim f2 as Import
:
Hide()
f2 = New Import
AddHandler f2.die, AddressOf killf2
f2.ShowDialog(Me)
Show()
Private Sub killf2()
f2.Dispose()
f2 = Nothing
End Sub
Form2
Public Event die()
Private Shadows Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles MyBase.FormClosing
Dispose()
Close()
e.Cancel = False
RaiseEvent die()
End Sub
I think you've got your events crossed. You want form1, containing an instance of form2, to listen for form2's form_closing event. Then you can set f2 = nothing.
Form1 should fully enclose form2.
here's an example:
Public Class MDIMain
Private WithEvents _child As frmViewChild
Friend Sub viewChildShow()
_child = New frmViewChild
_child.MdiParent = Me
_child.WindowState = FormWindowState.Maximized
_child.Show()
End Sub
Private Sub _child_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles _child.FormClosing
_child = Nothing
End Sub
don't add anything to form2, try
Dim f2 as Import
Hide()
f2 = New Import
f2.ShowDialog(Me)
Show()
Private Sub f2_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles f2.FormClosing
set f2 = nothing
End Sub
re: your comment
it goes back to form2 and continues processing the next statement in the the click event handler
that's a feature and it will cause this behavior. you need to make sure me.close or close me is the last statement in form2, that there's nothing else to execute.
What is this loop you speak of? The user interface (windows) is separate from any code that is running. In your class derived form Form, Code is allowed to run, both before the Form is created, and after the Form is destroyed. If the code tries to access user-interface objects then an exception might occur, but otherwise there is nothing stopping your code from running when there is no user interface.
If you want your "for" loop to exit then you must send it a signal somehow, e.g. by creating a boolean "quit" member variable. Set "quit=True" when your form closes, then have your "for" loop check whether it is true.

Where do I control the behavior of the "X" close button in the upper right of a winform?

I'm venturing into making my VB.NET application a little better to use by making some of the forms modeless.
I think I've figured out how to use dlg.Show() and dlg.Hide() instead of calling dlg.ShowDialog(). I have an instance of my modeless dialog in my main application form:
Public theModelessDialog As New dlgModeless
To fire up the modeless dialog I call
theModelessDialog.Show()
and within the OK and Cancel button handlers in dlgModeless I have
Private Sub OK_Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OK_Button.Click
Me.DialogResult = System.Windows.Forms.DialogResult.OK
Me.Hide()
End Sub
Private Sub Cancel_Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Cancel_Button.Click
Me.DialogResult = System.Windows.Forms.DialogResult.Cancel
Me.Hide()
End Sub
and that seems to work fine.
The "X" button in the upper right is getting me, though. When I close the form with that button, then try to reopen the form, I get
ObjectDisposedException was unhandled. Cannot access a disposed object.
I feel like I'm most of the way there but I can't figure out how to do either of the following:
Hide that "X" button
Catch the event so I don't dispose of the object (just treat it like I hit Cancel)
Any ideas?
The class of this dialog is System.Windows.Forms.Form.
Catch the FormClosing event and, if the reason is UserClosing, set Cancel on the event to true.
Something like the following:
Private Sub Form1_FormClosing(sender as Object, e as FormClosingEventArgs) _
Handles Form1.FormClosing
if e.CloseReason = CloseReason.UserClosing then
e.Cancel = true
Me.Hide()
end if
End Sub
Use Me.Close() to hide the form. To open it, use the following snippet:
If theModelessDialog.IsDisposed Then
theModelessDialog = New dlgModeless
End If
dlgModeless.Show()
If this is saving data, then you'll need to figure some way of storing it (perhaps in a static variable/s in the form). This is the proper way to do what you are trying to achieve though.
You'll also have to forgive me if my VB is off, it's been a while.
the formclosing event allows me to do a managed exit of the form so I have included a question to confirm to exit. I also have a form flag bterminate to force the cancel where i want it to and therefore not ask the question. Thanks your suggestion helped me as well :)
Dim msgboxresponse As MsgBoxResult
If e.CloseReason = CloseReason.UserClosing Then
If Not Me.bTerminate Then
msgboxresponse = MsgBox("Are you sure you want to cancel adding?", _
MsgBoxStyle.Question + MsgBoxStyle.YesNo, Me.Text)
If msgboxresponse <> MsgBoxResult.Yes Then
e.Cancel = True
Return
End If
End If
End If
#John was Hiding the form in his code and the answers above provide a solution to that case. Often, though, you are not planning to use the form again, so you really do want the form to be Disposed. All Close related activities will be in one place if you Handle the FormClosing event using Me.FormClosing by adding it to anyCancel/Close/Exit code that you already have. e.g. in #John's case:
Private Sub Cancel_Button_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles Cancel_Button.Click, Me.FormClosing
....More code
Me.Dispose
End Sub
Note the use of the Me.Dispose instead of any existing Me.Close. If you leave the Me.Close you'll create an infinite loop. See this for the subtle differences between Close and Dispose.
Agree with handling the FormClosing event. Or change the properties on the form to hide the system X control.
I've tried everything and it didn't work
if you just want to close, without showing an messagebox, you will just need:
Private Sub FORM1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
>e.Cancel = False
>FORM2.Show() (if you want to show another form)
End Sub
Hope this helps you...!