Introduction
In windows forms projects, the default behavior of the code is to start with a default form "Form1", and let the user add buttons to navigate to other forms. If as a developer, you wish to let the user go backwards as well as forwards in a series of forms, or even to visit the same form repeatedly, but with a different context, then here is a better way.
Using the code
When you run this code, you will see the following: An initial form will come up, with two NEXT buttons. Each NEXT button goes to a different form. If you click on the NEXT button with the yellow font, you will go to the 'yellow form', and if you click on the button with the red font, you will go to the 'red form'. Both the red and yellow forms have 'back buttons' that will take you back to the first form. If you click 'Next' on either the yellow or the red form, you will end up in the final form. This form also has a BACK button, but in addition, it has a SELF button. The SELF button calls the final form again, but a page counter is visibly incremented each time. When you click BACK, you reverse the action of the 'SELF' button, and the page counter gets decremented, until it is zero again, and then next click of the BACK button takes you back to the prior form (either the red form or the yellow form in this particular case).
Adapting the code to your project
When you adapt this code to your own project, you can use 'Module1' as is. It has a subroutine called 'Main' in it, and that routine has to be the startup routine of your VB project. To make it the startup routine, you have to do the following:
- Add the Module to your project (right click on the solution in 'solution explorer' and choose 'Add existing item')
- At the menu on the top of Visual Studio, click on 'Project'. The dropdown choices include (at the very bottom), the properties of your project. Choose that menu choice.
- Find the checkbox labeled 'Enable Application Framework'. If it is checked, then uncheck it (clear the checkbox)
- Find the dropdown list on the page that is titled 'Startup object'. Choose 'Sub Main' from the choices in this list
- If the first routine in your project is named 'Form1' then you do not have to modify Module1. If it has another name, perhaps 'FormJamesPictures", then replace the line: "
.nextForm = Form1
" by ".nextForm = FormJamesPictures
"
(This of course assumes that you don't already have a sub Main in your project that you used for other purposes.)
The code works as follows. In Module1's sub Main, you have a loop that starts with the first form. Each form is responsible for indicating what the next form in the series is. To do this, it fills a structure with that information, and pushes that structure onto a stack (the stack is declared in Module1). The advantage of a stack is that when the user wants to navigate backwards with BACK buttons, you can always find the prior form by popping the stack.
Here is the structure that the stack uses
Public Structure structNav
Dim nextForm As Form
Dim message As String
Dim oldForm As Form
Dim page As Integer
End Structure
The meaning of the fields are as follows.
- '
nextForm
' is the next form you wish to go to. If you don't wish to go to a nextForm
, set it to NOTHING. - '
message
' is a message such as 'exit' (if you want to exit the program' or 'back' if the user wants to go back a screen. In the case of a message of 'back' or 'message', 'nextform' should be set to nothing. Conversely, if you are going to a next form, then message should be set to an empty string. - '
oldForm
' should be set to the form that is setting all these fields, which is easy to do, just set it to the keyword 'me
'. - 'page' is normally zero, unless you are trying to make your page call itself, with incrementing pages.
- Here are examples of NEXT, BACK, SELF and EXIT buttons and the code they should execute:
Private Sub ButtonNext_Click(sender As Object, e As EventArgs) Handles ButtonNext.Click
Dim ts As New structNav
With ts
.oldForm = Me
.message = ""
.nextForm = FormFinal
.page = 0
End With
theStack.Push(ts)
DialogResult = DialogResult.OK
End Sub
For 'next' (as above) the code is straightforward. You would start the 'ButtonNext_Click
' routine with your own code, which might check the validity of numbers or text that the user entered, and you end it with this code, where you declare a structure, fill the fields, and push it on the stack. It is important to realize that DialogResult = DialogResult.OK
(or DialogResult = DialogResult.Cancel
) must be the last line of your routine. In this case, we are saying the next form to go to is 'FormFinal
' (assuming you have a form of that hame)
Private Sub ButtonBack_Click(sender As Object, e As EventArgs) Handles ButtonBack.Click
Dim ts As New structNav
With ts
.oldForm = Me
.message = "back"
.nextForm = Nothing
.page = 0
End With
theStack.Push(ts)
DialogResult = DialogResult.OK
End Sub
The above routine is executed when the user wishes to go back to a prior form.
Private Sub ButtonExit_Click(sender As Object, e As EventArgs) Handles ButtonExit.Click
Dim ts As New structNav
With ts
.oldForm = Me
.message = "exit"
.nextForm = Nothing
.page = 0
End With
theStack.Push(ts)
DialogResult = DialogResult.OK
End Sub
The above code is for exiting the routine. You would also use it in a 'cancel' button, assuming the 'cancel' operation is meant to exit the program. If it isn't you would have to modify Module1
to handle Cancel.
Private Sub ButtonSelf_Click(sender As Object, e As EventArgs) Handles ButtonSelf.Click
Dim ts As New structNav
With ts
.oldForm = Me
.message = "self"
.nextForm = Me
.page = currentPageTs.page + 1
End With
theStack.Push(ts)
DialogResult = DialogResult.OK
End Sub
The above code shows how to call the same page multiple times, but each time with an incrementing page counter, can find uses in special applications. For example, suppose you are asking the user to create a quiz. You want him to fill out a question, and multiple choice answers for each question, and then repeat the process until he has no more questions in the quiz he is designing. You could do this all on one page, or, you could have a template where he creates all the details for the question, then proceeds to the next screen (which is really the same screen be reused, for the next queestion).
Questions on how to set up wizards that accomplish this functionality often show up in VB forums. This code shows it is simple to do, and you don't need to use features such as tab-controls, or disappearing panels. Thats all there is to it!