Form.Show vs Form.ShowDialog Cross Threading - vb.net

I have the following code which closes a loginform and opens the mainform
Sub Loadform(ByVal formName As Form)
Dim Thisform As Form = DirectCast(formName, frmLogIn1)
Thisform.Hide()
Dim frm As New frmMain
frm.ShowDialog() <- Problem
Thisform.Close()
End Sub
The mainform has a DevExpress SplashScreenManager which loads and unloads the splash screen automatically.
When I call frm.Show I get a cross thread exception when the SplashScreen closes.
If I call it using frm.ShowDialog it works OK. This inst new code. The application is approx 12 months old and this code was added at the start, however I am now having problems.
The original code (taken from a backup) is:
Me.Hide()
Dim main As New frmMain
main.Show()
Me.Dispose()
But that seems to be closing the mainform now.
Any ideas?

I do not quite understand your question. Do you want to use the old code? The new? What problem are you trying to solve?
Well, an explanation for you calling frm.Show() and Thisform.Close() is simple.
When you call frm.Show() the new form is opened on a second thread and the current form continues to execute its code normally, logically reaching a line of code Thisform.Close () in which it closes. Because it is the main form, when it is closed it tries to terminate all other forms, so it tries to close the form you just opened, so the cross-thread exception occurs (remember that the new form is Running on another thread ;) )
But when you call frm.ShowDialog () the operation is different. It does not start a new thread, it just directs to the new form, so any line of code after ShowDialog only runs when the new forum is closed;

Related

My main form is closing immediately

I have the situation that when I run my app my main form is closing immediately. I don’t know why, here is the code I’m using:
Public Sub Main()
...
form.Visible = True
form.Show()
...
End Sub
This code is from an app from vb6.0 upgraded to vb2013, obviously there is a lot of code in this app for to make a new app, please the problem is when I execute the program and the main form initialize it closes immediately.
Any help would be appreciated.
If you set the Startup Object of your application to a Sub Main and inside this Main you want to launch your form then your Main should be something like this
Public Sub Main()
Application.EnableVisualStyles()
Application.SetCompatibleTextRenderingDefault(False)
Application.Run(New Form1)
End Sub
Actually your code terminates immediately because you show the form non modally (form.Show()) and this means that the call exits immediately. Of course this also means that you program terminates because you exit from the Sub Main.

vb.net Closing multiple form and open another form

I have 2 forms open, my current form is in dialog box. Now I want to close that 2 forms and open another form.
Dim frmStg2 As New frmStageTwo
Dim frmStg1 As New frmStageOne
frmStg2.Show()
Me.Close()
frmStg1.Close()
But this code seems not working the frmStageOne is still open and showing frmStageTwo but I can't view that form.
This is what happen
You are trying to close a form instance that has not yet been opened.
When you use the New keyword you are declaring a new instance of an object (a Form in this case) which has it's own version of the base class's properties and fields.
In order to close an already existing instance of the form you can loop through the Application.OpenForms property.
For Each frm As Form In Application.OpenForms
If frm.GetType() Is GetType(frmStageOne) Then
frm.Close()
End If
Next
You could actually make it a method:
Public Sub CloseFormsOfType(ByVal TargetForm As Form)
For Each frm As Form In Application.OpenForms
If frm.GetType() Is TargetForm.GetType() Then
frm.Close()
End If
Next
End Sub
...and just call:
CloseFormsOfType(frmStageOne)

VB.NET Calling forms by Variable

I'm playing around in vb.net and would like to create a menu for my application. The application has an Main which is the MDI Parent and then has the sub forms that open up as the user browses the menu structure. I would like to track which form the user came from so that when they close their current form, it opens up the previous form they had open.
What I have so far is a public variable "FormTracking" which is a list of Form. The open form function works fine, but when they close the form and it calls the "OpenPreviousForm" function it fails as the previous form has been closed/disposed. How can i create a new instance of the form as calling "NEW" doesn't seem to work
Public FormTracking As New List(Of Form)
Public Sub OpenForm(theNewForm As Object)
'First Declare the new form
Dim f As Form = DirectCast(theNewForm, Form)
'Set the Forms parent
f.MdiParent = frmMain2
'Add the form to the tracking
FormTracking.Add(theNewForm)
'Show the form
f.Show()
End Sub
Public Sub OpenPreviousForm()
If modMenu.FormTracking.Count > 1 Then
Dim f As New Form
f = modMenu.FormTracking(modMenu.FormTracking.Count - 2)
'Set the Forms parent
f.MdiParent = frmMain2
'Remove the last item
modMenu.FormTracking.RemoveAt(modMenu.FormTracking.Count - 1)
'Show the form
f.Show()
Else
MessageBox.Show("Whoops, run out of forms.... ", "modMenu - OpenPreviousForm")
End If
End Sub
When opening a form it it calls:
modMenu.OpenForm(menupage_1)
me.close
And when closing a form, i try to call
modMenu.OpenPreviousForm()
The error i am getting when calling the above code is
"An unhandled exception of type 'System.ObjectDisposedExeption' occured in System.Windows.Forms.dll
Additional Information: Cannot access a disposed object
I understand i need to create the object again, but not sure how to using the functionality as above. Alternatively, if someone can present a better way of doing an application menu, please feel free to let me know.
Cheers
Use Me.Hide instead of Me.Close so you do not dispose the form.

Using thread to open form

I am currently studying VB.NET and I got question about using thread to open the form.
For example, when I click open button, then tread will start and open another form to adding or changing data.
Therefore, I tried to implement this part such as
Private Sub menu_Click(sender As Object, e As EventArgs) Handles menu.Click
Dim A As System.Threading.Thread = New Threading.Thread(AddressOf Task_A)
A.Start()
End Sub
Public Sub Task_A()
frmBuild.Show()
End Sub
However, I am getting error to open the frmBuild by thread. Do I need to use other method to open form?
And, How can we kill the thread when fromBuild closes?
This is almost always a bad idea. You shouldn't try to use a separate thread to open a Form - instead, open all of your forms on the main UI thread, and move the "work" that would otherwise block onto background threads. BackgroundWorker is a common means of handling the work.
That being said, if you need to do this for some unusual reason, you need to do two other things.
First, you need to set the apartment state of that thread. You also need to use Application.Run to display the form, and that form must be created on the proper thread:
Private Sub menu_Click(sender As Object, e As EventArgs) Handles menu.Click
Dim th As System.Threading.Thread = New Threading.Thread(AddressOf Task_A)
th.SetApartmentState(ApartmentState.STA);
th.Start()
End Sub
Public Sub Task_A()
frmBuild = New YourForm() ' Must be created on this thread!
Application.Run(frmBuild)
End Sub
In order to close the Form from the other thread, you can use:
frmBuild.BeginInvoke(New Action(Sub() frmBuild.Close()))
And, How can we kill the thread when fromBuild closes ?
The thread will automatically shut down when the form is closed, if it's written as shown above.

Showing another form in VB

I want to make a program with many forms in VB, I need to make a button that opens another form.
form2.open()
Do not use the default instance of the form(as has been shown in the other answers), instead
Dim foo As New Form2
foo.Show()
'or
'foo.ShowDialog()
If you want to show multiple instances of the same form this
Form2.Show()
Form2.Show()
will not work.
This will
Dim foo As New Form2
foo.Show()
Dim bar As New Form2
bar.Show()
Simply the code will be
form2.show()
You can open a form inside yours as a MDI child, or you can "open" your new form in a new window with this methods:
form2.Show()
form2.ShowDialog()
Read here and here about them.
As SysDragon already mentioned,
.Show()
.ShowDialog(owner)
are the methods you can use.
If the calling Form should be frozen until the new opened one is closed again, then you should use ShowDialog.