Link to home
Start Free TrialLog in
Avatar of glass_snake
glass_snake

asked on

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!
Avatar of Howard Cantrell
Howard Cantrell
Flag of United States of America image

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
Avatar of glass_snake
glass_snake

ASKER

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 :)
ASKER CERTIFIED SOLUTION
Avatar of natloz
natloz

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial