switching between open forms

bones

Well-known member
Joined
Aug 23, 2014
Messages
143
Programming Experience
Beginner
In it's current state, my app will display multiple forms at the same time but you can only access the last form opened. How does one allow for having multiple forms open and allow switching between them?
 
but you can only access the last form opened
It sounds as you have shown the other form with ShowDialog method, use Show method instead.

Having multiple windows open in an application, when they are not modal dialogs (ShowDialog) is rare, unless they are modeless dialogs (tool windows) or MDI childs.
For modeless dialogs you should also set these windows Owner (to show/hide/close when owner/main form does) or use Show(owner) method, and ShowInTaskbar=False (so only main form shows in taskbar). Modeless dialog also usually have FormBorderStyle set to one of the ToolWindow options.
 
It sounds as you have shown the other form with ShowDialog method, use Show method instead.

Having multiple windows open in an application, when they are not modal dialogs (ShowDialog) is rare, unless they are modeless dialogs (tool windows) or MDI childs.
For modeless dialogs you should also set these windows Owner (to show/hide/close when owner/main form does) or use Show(owner) method, and ShowInTaskbar=False (so only main form shows in taskbar). Modeless dialog also usually have FormBorderStyle set to one of the ToolWindow options.

Initially I used .show buy after I built a menu it cause issues and I had to use showdialog... Why would creating the menu cause that?
 
Initially I used .show buy after I built a menu it cause issues and I had to use showdialog... Why would creating the menu cause that?
How are we supposed to know, particularly given that we don't even know what issues they were? Almost certainly your issues arose because you did something wrong. To know what you did wrong, we'd have to know what you did. To know how to address your issues, we'd have to know what they are.
 
How are we supposed to know, particularly given that we don't even know what issues they were? Almost certainly your issues arose because you did something wrong. To know what you did wrong, we'd have to know what you did. To know how to address your issues, we'd have to know what they are.

Yes you would...:anonymous: but I can't remember now specifically what the error was. I changed form.show() to .showdialog() per someones advice and it fixed the problem. After receiving your first answer I went back in the code and set them back to .show...one at a time hoping it would blow up again so I could post the error...but it works fine... I just didn't get back here to post that yet...

Thinking it was perhaps something common you have run across I thought perhaps you could have pointed me to a quick solution... sorry for the misunderstanding..
 
How are we supposed to know, particularly given that we don't even know what issues they were? Almost certainly your issues arose because you did something wrong. To know what you did wrong, we'd have to know what you did. To know how to address your issues, we'd have to know what they are.

I got a form throw the error... "Cannot Access A Disposed Object"

I open it from the context menu on the main form. It opens.
I close it with the default X on the form. It closes.
I go back to the main form's context menu and try to open it.... I get the error.

That form has a DGV bound to an Access datasource. It is the ONLY form that blows up like that too. It is Access 2003 also if that matters at all.

Why?
 
I read this link VS 2008 Cannot access a disposed object.-VBForums

Here is the stack trace

at System.Windows.Forms.Control.CreateHandle()
at System.Windows.Forms.Form.CreateHandle()
at System.Windows.Forms.Control.get_Handle()
at System.Windows.Forms.Control.SetVisibleCore(Boolean value)
at System.Windows.Forms.Form.SetVisibleCore(Boolean value)
at System.Windows.Forms.Control.Show()
at QuickStart_Communicator.frmMain.OrificeCalculationsMenuItem1_Click(Object sender, EventArgs e) in xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\Form1.vb:line 1131
at System.Windows.Forms.ToolStripItem.RaiseEvent(Object key, EventArgs e)
at System.Windows.Forms.ToolStripMenuItem.OnClick(EventArgs e)
at System.Windows.Forms.ToolStripItem.HandleClick(EventArgs e)
at System.Windows.Forms.ToolStripItem.HandleMouseUp(MouseEventArgs e)
at System.Windows.Forms.ToolStripItem.FireEventInteractive(EventArgs e, ToolStripItemEventType met)
at System.Windows.Forms.ToolStripItem.FireEvent(EventArgs e, ToolStripItemEventType met)
at System.Windows.Forms.ToolStrip.OnMouseUp(MouseEventArgs mea)
at System.Windows.Forms.ToolStripDropDown.OnMouseUp(MouseEventArgs mea)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
at System.Windows.Forms.ToolStrip.WndProc(Message& m)
at System.Windows.Forms.ToolStripDropDown.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.Run(ApplicationContext context)
at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()
at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()
at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String[] commandLine)
at QuickStart_Communicator.My.MyApplication.Main(String[] Args) in 17d14f5c-a337-4978-8281-53493378c1071.vb:line 81
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
 
I got a form throw the error... "Cannot Access A Disposed Object"

I open it from the context menu on the main form. It opens.
I close it with the default X on the form. It closes.
I go back to the main form's context menu and try to open it.... I get the error.

That form has a DGV bound to an Access datasource. It is the ONLY form that blows up like that too. It is Access 2003 also if that matters at all.

Why?

If you open a form by calling its Show method, closing it by any means will dispose it, meaning that it cannot be displayed again. If you want to display another form then you must create another instance. Here's how I would do that:
Private childForm As SomeForm

Private Sub DisplayChildForm()
    If Me.childForm Is Nothing OrElse Me.childForm.IsDisposed Then
        'Create and display a new instance.
        Me.childForm = New SomeForm
        Me.childForm.Show()
    Else
        'Focus the existing instance.
        Me.childForm.Activate()
    End If
End Sub
The most important feature of that code in relation to your issue is the test of the IsDisposed property. The first time that method is executed, `childForm` will be Nothing. On subsequent executions, it will not be Nothing but, if the last form has been closed, IsDisposed will be True. In either case, a new form will be created and displayed. If the last form displayed has not been closed, that form will receive focus.
 
If you open a form by calling its Show method, closing it by any means will dispose it, meaning that it cannot be displayed again. If you want to display another form then you must create another instance. Here's how I would do that:
Private childForm As SomeForm

Private Sub DisplayChildForm()
    If Me.childForm Is Nothing OrElse Me.childForm.IsDisposed Then
        'Create and display a new instance.
        Me.childForm = New SomeForm
        Me.childForm.Show()
    Else
        'Focus the existing instance.
        Me.childForm.Activate()
    End If
End Sub
The most important feature of that code in relation to your issue is the test of the IsDisposed property. The first time that method is executed, `childForm` will be Nothing. On subsequent executions, it will not be Nothing but, if the last form has been closed, IsDisposed will be True. In either case, a new form will be created and displayed. If the last form displayed has not been closed, that form will receive focus.


I don't have any of my forms setup as a child form. Using .show in the code for the menu I can open them from the menu and close them with the default X on the form. I can do it all day long and not receive that error message. What am I missing here? Why is it just that one particular form?
 
I don't have any of my forms setup as a child form. Using .show in the code for the menu I can open them from the menu and close them with the default X on the form. I can do it all day long and not receive that error message. What am I missing here? Why is it just that one particular form?

If only there was some way for us to see the actual code.
 
If only there was some way for us to see the actual code.

It's the first one that has the problem...orificeflowcalcs and it's only that form...the rest will not throw the error. Again, this form has a DGV with a connection to an Access.mdb ver 2003 The other forms DO NOT.
If I use .showdialog instead, it works fine. Certainly I can use that and be fine but I would still like to know why it's doing it.
VB.NET:
Private Sub OrificeCalculationsMenuItem1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OrificeCalculationsMenuItem1.Click
        'orificeflowcalcs.ShowDialog()
        orificeflowcalcs.Show()
    End Sub


    Private Sub ConfigurationsToolStripMenuItem1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ConfigurationsToolStripMenuItem.Click
        'configurations.ShowDialog()
        configurations.Show()
    End Sub


    Private Sub CalculationToolStripMenuItem1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CalculationToolStripMenuItem.Click
        'databasefields.ShowDialog()
        databasefields.Show()
    End Sub

The form load for the form

VB.NET:
Private Sub orificeflowcalcs_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'loads data into the 'ProFlow1DataSet.orificedata' table
        Me.OrificedataTableAdapter.Fill(Me.ProFlow1DataSet.orificedata)


    End Sub
 
Last edited:
Is "orificeflowcalcs" a variable (your instance) or a form type name (default form instance) ?
 
Is "orificeflowcalcs" a variable (your instance) or a form type name (default form instance) ?

It's the form name.

NOTE: I am comparing that form's properties with the properties of my other forms. I don't see anything different. I haven't added any code to any of the form close events.
 
What you're doing looks like it should be fine so either you're doing something wrong without realising it or something is broken in your project.

One possibility is that you think you're using the default instance but you actually aren't because you have declared a variable with the same name as the type and are therefore using that. In this code:
VB.NET:
    Private Sub OrificeCalculationsMenuItem1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OrificeCalculationsMenuItem1.Click
        'orificeflowcalcs.ShowDialog()
        [B]orificeflowcalcs[/B].Show()
    End Sub


    Private Sub ConfigurationsToolStripMenuItem1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ConfigurationsToolStripMenuItem.Click
        'configurations.ShowDialog()
        configurations.Show()
    End Sub


    Private Sub CalculationToolStripMenuItem1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CalculationToolStripMenuItem.Click
        'databasefields.ShowDialog()
        databasefields.Show()
    End Sub
you should right-click on the `orificeflowcalcs` and select `Go to Definition` or the like. If that navigates to a variable then that's your issue. If it doesn't then something in your project is broken and you may have to recreate that form.
 
Back
Top