Opening a second-form more than once error - vb.net

I have a button in form1 that opens form2. I do this using frm2.show(). It works totally fine for the first time that I open frm2, but when I close frm2 and click on the button in frm1 to open frm2 again, I get this error:
Can someone tell me how to solve it?
Edit: I have a module where I have my database connection and my declaration for the forms:
Public frmGame As New Game
Public frmPlay As New Play
Public frmFinish As New GameFinish
Public frmLogin As New Login
Public frmManage As New Manage
Public frmInsert As New Toevoegen
Where I open the form is just when I click on a button in form1.

Sounds to me like you are Close()ing frm2. Closing a form should dispose it and release its resources, so you can't simply Show() it again. Instead, you need to create a new instance of the object, like this:
frm2=new Form2()
frm2.Show()
If that doesn't work (perhaps because you don't want to re-initialize the form's data members), you could use Hide(), rather than Close() to temporarily hide the form during your program's execution.
If you need to prevent the form from being closed with the X button, you can do this with a few different methods:
The best way to go may be to hide or disable the close button. Read up on This post to get a better idea of how to do that.
You can use the FormClosing event, either from inside frm2 or from the main window. Set the Cancel property on the FormClosingEventArgs object that gets passed in. The problem here is that you will need to provide an additional code path to close the form when you actually want it to close. The CloseReason property of the FormClosingEventArgs object should give you a way to handle that properly. Needless to say, this is probably the riskiest way to do things, since you need this window to close when the application shuts down, but you're also intentionally block that from happening.
You could catch the FormClosed event in the the form that spawns frm2, then create a new instance of the window. Again, you'll need to provide a code path to allow the window to close when the application shuts down.
In all, method 1 is probably the safest. You can close the window with .Close() when the application shuts down, but the user can't close it with the X button.

Related

What Is the Correct Way to Close and Reopen a Form Declared as Public?

My problem pertains to a COM add-in for Microsoft Excel. The use case is as follows: 1. User clicks the add-in's button on the ribbon. 2. A form window appears. 3. User interacts with the form window and clicks an OK button. 4. Various reports are generated, while a progress bar on the form window shows progress. 5. At the end of the process, the form window closes.
The process works as designed on the first run, but after the form window has been closed there is no way to start a new "session." From the user's perspective the add-in button becomes non-responsive. When run in debug mode from Visual Studio, clicking the add-in button a second time generates an error message: "Cannot access a disposed object."
Clearly something is wrong with the way I have hooked everything up, but I haven't been able to find a simple description of how to do it correctly. Here is what I have:
In a public class a number of public (or "global" variables) are declared; the form is also declared and instantiated here:
Public Class GlobalVariables
Public Shared FormInstance As New MyFormDesign
End Class
The reason for declaring the form as a public object is to be able to be able to send progress values from various different subs and functions. The GlobalVariables class is imported by all modules that require it.
Behind the ribbon button is a single line of code:
FormInstance.Show()
Clicking the button instantiates and shows the form as intended. To keep things simple we can ignore the bulk of the code; simply clicking the "Cancel" button will trigger the problem. The code behind the "Cancel" button is straightforward:
Me.Close()
GC.Collect()
After closing the form it is no longer possible to create a new instance, per the error message cited above.
I don't really understand what is going on here, but it looks to me like the GlobalVariables class, once created, persists until the end of the Excel session. If that is correct the problem could presumably be cured by instantiating the form in a standard module. Instead of attempting to revive a form that has been disposed, the add-in would just create a new instance each time the user clicks the button. But if I go that route I can't figure out how to send progress values from other subs back to the form. It seems like a Catch-22.
There has got to be a way to both (a) create the form as a public object, and (b) create and destroy a new instance each time the add-in is run. Right? What am I doing wrong?
It has been a long journey, but I finally found out how to build the functionality described in my question. I will post the answer here, as it may help others in the future.
The challenge was to declare a form as Public in order to make it accessible throughout the project, so that subs and functions can send progress updates back to the form.
The problem was that the form, when declared and instantiated as described in my question, can only be created once per Excel session.
The solution is to declare the form as Public without instantiating it, then access it via a Public ReadOnly Property.
First, declare FormInstance as a public variable without instantiating it:
Public FormInstance As MyFormDesign
Second, define a Public ReadOnly Property. This establishes a way to call the form:
Public ReadOnly Property CallMyForm() As MyFormDesign
Get
Return FormInstance
End Get
End Property
Third, the ribbon button's Click event instantiates and shows the form:
Private Sub Button1_Click(sender As Object, e As RibbonControlEventArgs) Handles Button1.Click
FormInstance = New MyFormDesign
FormInstance.Show()
End Sub
Now a new form instance will be created each time the ribbon button is clicked, but the form can still be accessed via the CallMyForm property.
Instead of ...
FormInstance.BackgroundWorker1.ReportProgress(i)
... we will use:
CallMyForm.BackgroundWorker1.ReportProgress(i)
This solves the conundrum laid out in the question.

Cannot access disposed form despite creating it immediately prior

I have a windows form (VB/.NET) that I want to open when I click a particular button. It opens correctly the first time, but after closing it and trying to re-open it I get this error:
"ObjectDisposedException was unhandle: Cannot access a disposed object. Object name: frm8100VI"
Now, I create a new instance of the form right before calling it's show() method, so I don't know how it's disposed:
Dim form as New frm8100VI
form.show()
This code works correctly the first time it's called, but after closing the form once it will not work correctly again, saying the object has been disposed. To close the form all I do is call me.close()
I'm guessing you have your "Dim form as new frm8100VI" located in a space inside another object or in a public space where it never goes out of scope.
Once you have said "form.show", the user has worked with the form, closes the form.
At this point you cannot call "form.Show" again on the same form object (it is disposed).
You MUST reassign "form = New frm8011VI" again before you can call "form.show" (to re-iterate, after it has been disposed show fails)
If your trying to persist the information inside the "form" object then you should not actually close the form; in the form_unload event you show cancel the closing of the form and simply hide the form. If you do that you can call "form.Show" again without issue.

vb.net Prevent Form 1 from activating when form 2 is clicked

im having a similar problem like the solution here Prevent main form from appearing when showing another form . but some of the suggestions were to minimize the main app so it doesnt show, which i cant do because my main app is supposed to be a desktop to be underneath all other apps to replace the windows desktop. And the second forms are supposed to be sticky notes. so i cant minimize the main window cause it has the user background and other controls. i tried making the parent of the notes a Nothing pointer, a pointer to the desktop, creating the form through a dll but i had no success.
My main problem is that when i click a note (form2) form1 comes up, even with form1 having the WS_EX_NOACTIVATE in the createparams. form1 does the form2.show() but they shouldn't be attached.
Another reason im having trouble with the solutions preseted in that post is that they are for delphi and im doing it in vb.net.
All i need is being able to click on the controls and write in the note without bringing the main form behind the note. either making them independent, or making the note not focusing the first form or being able to operate the note without it activating. i dont know. my last resource is to attach my main form to the desktop but i've heard is the worst thing you can do because it can cause problems hanging the system.
If you want both forms to co-exist but don't each to interfere with the other: In this case, then you might want to have a third Form that calls both Form1 and Form2 to be opened, and let me suggest and MDI Form with Form1 and Form2 as children forms of the MDI form
'============== my previous post ========================
You can force the user to first dismiss Form2 then allow him to go back to form1 by showing Form2 as Modal form. Here is how to display Form2 as modal
Dim f2 as New Form2
f2.ShowModal()
If that does not work, try this
Dim f2 as New Form2
f2.Show(True)

Start a new form on closing one. VB.Net

When my program runs it closes form1 after a few seconds. Depending on what happened during form1's lifespan I may want to open form2. Normally I would just make a new instance of form2 and use the show() method. But form2 is then a child of form1 and then also closes. Does any body have an idea on how to get this to work? thanks.
in the properties of the project make sure to select "When last form closes" in the shutdown mode dropdown
Before you close form1 set form2.Owner property to Nothing. This will need to be done before the FormClosing event of form1, since form2 will already be scheduled for closing by then.
But this only works if form2 actually is a child of form1.
try looking for the MVC or MPV patterns. This is than best done in the controller or presenter and will not give you the problems that you describe.

VB.NET: How to close and re-open a dialog in this case?

I'm developing a WinForms app in VB.NET, that handles sets of style data, and when the user clicks on another set's label, it prompts through a dialog "You are leaving this style preset to edit another one. keep changes on this one? [Yes] [No]"
But, I'm facing the problem that, when the user clicks either option, and the dialog closes, everything has to be refreshed, and loading the form again seems a good option.
I've tried putting a public sub on a module, that does this:
Public Sub CloseOpenStyleDlg()
KeepOrDiscardPrompt.Close()
StylesDlg.Close()
StylesDlg.ShowDialog()
End Sub
But as soon as that sub is called from the prompt, it crashes the application. (doesn't show an error in debug, simply crashes) How should I, from a given dialog, close the dialog, it's parent, and re-open it's parent? (which triggers all the Dialog_Load() code of the parent)
Thanks in advance! :)
You need to instantiate the dialog again. If I take your code for example:
Public Sub CloseOpenStyleDlg()
KeepOrDiscardPrompt.Close()
StylesDlg.Close()
StylesDlg = new StylesDlg()
StylesDlg.ShowDialog()
End Sub
When a form is closed, all resources created within the object are closed and the form is disposed.
If you want to reuse the Window instance use StylesDialog.Hide() function instead.