Switching between forms -- is there a better way?

Posted on 2004-11-12
Last Modified: 2010-04-23
I've been programming in the VB family of languages for almost a decade now.  I made the switch to 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, you're supposed to switch between forms as follows...

Dim frm As New frmMainMenu()

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

(on form B's close button)

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()

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!
Question by:glass_snake
    LVL 27

    Expert Comment

    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()

            'This call is required by the Windows Form Designer.

            '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
                End If
            End If
        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()
            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
            If bLogin = True Then                     '<------- Global Var
                System.Windows.Forms.Application.Run(New frmMainForm)
            End If
        End Sub
    End Class

    Author Comment

    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 :)
    LVL 7

    Accepted Solution

    I use ShowDialog with multiple levels of forms....

    frmLogin -> frmMain -> frmPurchaseOrder -> frmPODetail

    basically nesting with Modal forms as I 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.

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone.

    Featured Post

    Highfive Gives IT Their Time Back

    Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

    This tutorial demonstrates one way to create an application that runs without any Forms but still has a GUI presence via an Icon in the System Tray. The magic lies in Inheriting from the ApplicationContext Class and passing that to Application.Ru…
    I think the Typed DataTable and Typed DataSet are very good options when working with data, but I don't like auto-generated code. First, I create an Abstract Class for my DataTables Common Code.  This class Inherits from DataTable. Also, it can …
    It is a freely distributed piece of software for such tasks as photo retouching, image composition and image authoring. It works on many operating systems, in many languages.
    In this sixth video of the Xpdf series, we discuss and demonstrate the PDFtoPNG utility, which converts a multi-page PDF file to separate color, grayscale, or monochrome PNG files, creating one PNG file for each page in the PDF. It does this via a c…

    737 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    22 Experts available now in Live!

    Get 1:1 Help Now