Page 1 of 1

Simple Navigation Rate Topic: //<![CDATA[ rating = new ipb.rating( 'topic_rate_', { url: 'http://www.dreamincode.net/forums/index.php?app=forums&module=ajax&section=topics&do=rateTopic&t=230332&amp;s=6e07d2eedad41d694d079e0876f1092f&md5check=' + ipb.vars['secure_hash'], cur_rating: 0, rated: 0, allow_rate: 0, multi_rate: 1, show_rate_text: true } ); //]]>

#1 modi123_1

• Suitor #2

Reputation: 10480
• Posts: 40,440
• Joined: 12-June 08

Posted 02 May 2011 - 02:26 PM

The concept of basic navigation in a set of data is one that stymies most beginners. Trying to visualize how a set of data should be moved through - backwards and forwards - is a tricky situation. There are many moving parts and some sneakily complex code.

For this small tutorial let us think of our scenario being a simple non functioning quiz. You have a series of data objects you need displayed. Those objects contents are different, but their format is the same. You want to be able to move forward and backwards to access the next and the previous questions. More advanced options will be offered below.

What will we need:
- a new project.
- a form on that project.
- a small class to hold our question and answers
- a quick visual quiz layout
- a counter to tell us what question we are on.

The critical points are the next and previous states. We know they can be enabled or disabled but when? I am thinking there are five critical scenarios:
1. When at the first position of the array with more elements in the array
2. When at the last position of the array with more elements in the array
3. When in the middle of the array with more elements in the array
4. When the array only has one element.
5. When the array has zero elements.
5.1 When the array is nothing

RE: #1: In this scenario I want previous to be disabled (can't go back farther than the first element!) and the next enabled.
RE: #2: In this scenario I want next to be disabled (can't go past than the last element!) and the previous enabled.
RE: #3: I want both next and previous enabled. Free movement!
RE: #4: I want both next and previous disabled. If there are no more elements then there are no more places to go!
RE: #5: When the array length is zero both buttons should be disabled. I could add fancy error handling but that distracts from the navigation.
RE: #5.1 Yes zero elements and nothing are different. Just a quick 'if statement' wrapper takes care of this.

A quick class to hold our question and answers:
```Public Class MultiChoiceQuestion
'-- A simple multiple choice class.  It stores a question, three possible answers, and does not store the 'right answer'.  That's an advanced activity for you later.
Private _sQuestion As String = String.Empty
Private _sAnswer1 As String = String.Empty
Private _sAnswer2 As String = String.Empty
Private _sAnswer3 As String = String.Empty

'-- Basic properities to set and get your variables.
Public Property Question As String
Get
Return _sQuestion
End Get
Set(value As String)
_sQuestion = value
End Set
End Property

Public Property Answer1 As String
Get
End Get
Set(value As String)
End Set
End Property

Public Property Answer2 As String
Get
End Get
Set(value As String)
End Set
End Property

Public Property Answer3 As String
Get
End Get
Set(value As String)
End Set
End Property

'-- Two constructors.

Public Sub New()
'-- Default constructor - nothing much to do here.
End Sub
Public Sub New(ByVal question As String, ByVal answer1 As String, ByVal answer2 As String, ByVal answer3 As String)
_sQuestion = question
End Sub
```

```'-- the form we are using.
'-- A collection of question objects.  This is an array, but in the future I will want flexibility of being a "list(of".
Private _oListOfQuestions() As MultiChoiceQuestion = Nothing '--New List(Of MultiChoiceQuestion)
Private _lCurrent As Int32 = 0 '-- This counter will help us keep track of where we are in the array of the questions.

Public Sub New()
' This call is required by the designer.
InitializeComponent()

' Add any initialization after the InitializeComponent() call.
'-- 1.0  Add our questiosn to the array.

'-- Only continue if there is an array declared.
If _oListOfQuestions IsNot Nothing Then
'-- 2.0  Determine how the buttons should be displayed.
SetButtonState()

'-- 3.0 Load question information
End If
End Sub

'-- 1.  Redefine the array of questions to five.  That's how many we should be able to cycle through.
_oListOfQuestions = New MultiChoiceQuestion(4) {}
'-- 2.  Add our questions and answers.
_oListOfQuestions(0) = New MultiChoiceQuestion("Two plus two equals?", "0", "4", "Chair")
_oListOfQuestions(1) = New MultiChoiceQuestion("The sky is what color?", "Purple", "Gray", "Blue")
_oListOfQuestions(2) = New MultiChoiceQuestion("Columbus sailed the ocean blue in? ", "1842", "1642", "Go suck on a shoe!")
_oListOfQuestions(3) = New MultiChoiceQuestion("Our moon is made up of?", "Cheese!", "It doesn't exist!", "Rocks")
_oListOfQuestions(4) = New MultiChoiceQuestion("A leopard cannot change its?", "Spots", "Stripes", "Underware")

'-- a quick test of nothing elements.
'_oListOfQuestions = Nothing
'-- a quick test of zero elements
'ReDim _oListOfQuestions(-1)
'-- A quick test to see what happens when there is only one element!
'ReDim _oListOfQuestions(0)
''-- 2.  Add our questions and answers.
'_oListOfQuestions(0) = New MultiChoiceQuestion("Two plus two equals?", "0", "4", "Chair")
End Sub

Private Sub SetButtonState()
'-- 1.  We want the 'next' to be enabled in all conditions except when it is the last question in the array
uxButtonNext.Enabled = _lCurrent < _oListOfQuestions.Length - 1
'-- 2.  We want the 'previous' enabled except when we are on the first element of the array.
uxButtonPrevious.Enabled = _lCurrent > 0
End Sub

'-- 1.  It is always important to show the navigation.
uxLabelQuestionNumber.Text = String.Format("{0} of {1}", _lCurrent + 1, _oListOfQuestions.Length)

If _oListOfQuestions.Length > 0 Then
'-- 2. Set the question and answers
uxLabelQuestion.Text = _oListOfQuestions(_lCurrent).Question

'-- 3. Reset the current selected.  Remember - just because the radiobuttons text change doesn't mean the control changes.  The controls are static.
End If
End Sub

Private Sub uxButtonPrevious_Click(sender As System.Object, e As System.EventArgs) Handles uxButtonPrevious.Click
'-- 1.  Make sure decrementing won't put is below zero!
If _lCurrent - 1 >= 0 Then
_lCurrent -= 1
SetButtonState()
End If

End Sub

Private Sub uxButtonNext_Click(sender As System.Object, e As System.EventArgs) Handles uxButtonNext.Click
'-- 1.  Make sure incrementing won't put is over the max number of questions!
If _lCurrent + 1 < _oListOfQuestions.Length Then
_lCurrent += 1
SetButtonState()
End If
End Sub

End Class
```

The designer.vb file:
Spoiler

While the code could be re-factored better, it shows the clear outline of what is going on. You should be able to run the copied code and navigate forward and backwards with in the current array. The information should update appropraitely

When the form starts it loads up the questions, sets the button state, and shows the first question. We are on the first element so we know the 'previous' should be disabled and the next enabled (since we have five questions).

Now when the next and previous buttons are clicked they first check to make sure can decrement. This is extra caution so you do not get to index values below zero or greater than the number of the elements! The buttons have their states updated. And the new question information is loaded up.

This tutorial could be adapted in multiple ways. Data grids, toolbar buttons, and so forth. Here are some advanced modifications you could easily try out on your own.