Page 1 of 1

Simple Navigation Rate Topic: -----

#1 modi123_1  Icon User is online

  • Suitor #2
  • member icon



Reputation: 9277
  • View blog
  • Posts: 34,789
  • 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
    '-- private _oRightAnswer.

    '-- 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
            Return _sAnswer1
        End Get
        Set(value As String)
            _sAnswer1 = value
        End Set
    End Property

    Public Property Answer2 As String
        Get
            Return _sAnswer2
        End Get
        Set(value As String)
            _sAnswer2 = value
        End Set
    End Property

    Public Property Answer3 As String
        Get
            Return _sAnswer3
        End Get
        Set(value As String)
            _sAnswer3 = value
        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
        _sAnswer1 = answer1
        _sAnswer2 = answer2
        _sAnswer3 = answer3
    End Sub


'-- the form we are using.
Public Class BasicNavigation
    '-- 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.
        AddQuestions()

        '-- 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
            LoadQuestion()
        End If
    End Sub

    Private Sub AddQuestions()
        '-- 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

    Private Sub LoadQuestion()
        '-- 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
            uxRadioButtonAnswer1.Text = _oListOfQuestions(_lCurrent).Answer1
            uxRadioButtonAnswer2.Text = _oListOfQuestions(_lCurrent).Answer2
            uxRadioButtonAnswer3.Text = _oListOfQuestions(_lCurrent).Answer3

            '-- 3. Reset the current selected.  Remember - just because the radiobuttons text change doesn't mean the control changes.  The controls are static.  
            uxRadioButtonAnswer1.Checked = True
        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()
            LoadQuestion()
        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()
            LoadQuestion()
        End If
    End Sub

End Class


Attached Image

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.

Advanced fun:

- Make it so the quiz "remembers" the already selected choice before it changes view.
- Make a tally and validation screen as the last one. Once there you cannot navigate until the quiz is restarted.
- A textbox that when a number is typed in it jumps to that question.
- I prefer having "First" and "Last" as well - how would I add those buttons?

Is This A Good Question/Topic? 2
  • +

Page 1 of 1