Switching between forms -- is there a better way?

I've been programming in the VB family of languages for almost a decade now.  I made the switch to VB.net about two years ago, but something has always bugged me.  

Let's say I have an application with three forms.  A Login page, a Main Menu, and a Details page (for order details or whatever).  The flow of the application is that you go from one page to another, in the order I just listed them (you login, see the main menu, then view the details from the main menu).

The way I was taught VB.net, you're supposed to switch between forms as follows...

Dim frm As New frmMainMenu()
frm.Show()
Me.Hide()

This method, however, seems to have three big problems:

1. If the user exits the application while any form is hidden, the application still hangs out in memory since a form is still technically open.

2. You can add "End" to the Dispose event, which will kill the app when the form closes.  But that has its own problems.  Depending on the flow of the app, closing a form may ne supposed to kill the app sometimes, but not others.

3. It also creates a memory leak.  For example, if the user keeps going back to the Main Menu, you're loading a new copy of it into memory each time.  

So what are my alternatives?

Well, I can give Form B a property that will accept Form A itself.  Such as:

(On form B)
Public MainMenu as frmMainMenu

(On form A's button to open form B)
Dim frm As New frmDetails()
frm.MainMenu = Me
frm.Show()
Me.Hide()

(on form B's close button)
Me.Hide
MainMenu.Show

That way I can at least reload the same hidden form without creating a new one.  That fixes problem #3 in my list, but not #1.  If I close the Main Menu, form B is still hanging out in memory and keeping the application running.

So then I tried:

Dim frm As New frmMainMenu()
frm.Show()
Me.Dispose()

However, when I run that, it shuts down the entire application; it doesn't dispose just the current form.  Forgive my ignorance, but I can't even figure out why :)  According to the context help, "Me" is a reference to the current form and not he application.  And I'm certain there's nothing I added to the Dispose event (such as an "End" statement).  But when I dispose the first form, there goes the app.

So what're my options?  How do I open Form B and just completely knock Form A from memory?  In other words, how do I build the app so that I only have one form open at once?  There must be a better way to do this that I just wasn't taught.

Thanks for your help!
glass_snakeAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

planoczCommented:
here is a sample of what I use....

Public Class frmMainForm                                          '<------   This is a MDI Form
    Inherits System.Windows.Forms.Form

#Region " Windows Form Designer generated code "

    Public Sub New()
        MyBase.New()

        'This call is required by the Windows Form Designer.
        InitializeComponent()

        'Add any initialization after the InitializeComponent() call

    End Sub

    'Form overrides dispose to clean up the component list.
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If Not (components Is Nothing) Then
                components.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    End Sub

    'Required by the Windows Form Designer
    Private components As System.ComponentModel.IContainer

    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.  
    'Do not modify it using the code editor.
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        '
        'frmMainForm
        '
        Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
        Me.ClientSize = New System.Drawing.Size(292, 273)
        Me.IsMdiContainer = True
        Me.Name = "frmMainForm"
        Me.Text = "frmMainForm"

    End Sub

#End Region
    'Run the application
    'The main entry point for the application
    <STAThread()> Shared Sub Main()
        Dim objForm As New frmLogin
        objForm.ShowDialog()
        If bLogin = True Then                     '<------- Global Var
            System.Windows.Forms.Application.Run(New frmMainForm)
        End If
    End Sub
End Class
0
glass_snakeAuthor Commented:
That would work for just one form (since it creates a pop-up dialog), but what if the application was more complex than that?

In the real application I'm building, you have a Login screen that goes to the Main Menu.  The Main Menu can go to Add, Review, and Post pages.  The Add page creates a new record and then goes to the Edit page.  The Review page lists existing timesheets and then goes to the Edit page.

So I could theoretically have a whole crapload of forms hanging around at once :)
0
natlozCommented:
I use ShowDialog with multiple levels of forms....

frmLogin -> frmMain -> frmPurchaseOrder -> frmPODetail

basically nesting with Modal forms as I go...to get back to main you need to close all forms...on all forms if the onClose event occurs the app just returns to the previous form...if Main is closed the Application.exit event is fired to kill the whole application.

I also use the same form for ADD/EDIT....I have a hidden textbox on every form that has either the Primary Key of the record being editted, or the word "NOID" which means the user is adding a new record...if the user hits save...the Hidden ID is updated with the ID returned by my stored procedure and the form is now in EDIT mode. I have a label that tells the user whether or not they are in EDIT or ADD Mode.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Visual Basic.NET

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.