Click here to Skip to main content
15,867,308 members
Articles / Web Development / ASP.NET
Article

Integrated Quiz WebApp with Graphical Score Report

Rate me:
Please Sign up or sign in to vote.
4.13/5 (22 votes)
21 May 2005Ms-PL1 min read 81.2K   5.4K   82   7
Integrated online quiz app with graphical score report. Users can bookmark questions in order to review in the end.

Image 1

Background

The quiz application demonstrated here allows users to proceed with multi-choice questions like in an IQ Quiz. The database is a simple XML file. The application is a single web user control. The data holder between the pages is the Session bag (Viewstate[ data ]).There are three panels within our quiz user control. They are Quiz panel, Review panel and Score Report panel. I have used my own progress bar control within the Score Report...

Database

Our database is a simple XML file:

XML
<?xml version="1.0" encoding="utf-8" ?> 
<quiz>
  <mc>
     <question correctAnsNo='1'>Which of the fol....?
     </question>
     <answer correct='No' ><![CDATA[  <img src="x...]]>
     </answer>
     <answer correct='No' ><![CDATA[  <img src="x...]]>
     </answer>
     <answer correct='Yes'><![CDATA[  <img src="x...]]>
     </answer>
     <answer correct='No' ><![CDATA[  I Don't Know  ]]>
     </answer>
  </mc>
</quiz>

Using the code

Our quiz user control has four methods:

  • ShowQuestion(int _qNo)
  • Review()
  • ReAnswer()
  • ShowResult()

The code

First, there are some common member variables:

C#
//create xmlDocument holder
XmlDocument doc=new XmlDocument();
//create empty navigator in order to navigate
//through our XMLDocument
XPathNavigator nav;
//to loop through
XPathNodeIterator nodeItrator;
//hold user Answers
ArrayList historyALst=new ArrayList();
//hold bookmarked Question(s)
ArrayList bookmarkLst=new ArrayList();
//used to replace index 1 by A and 2 by B ....etc
char[] perfix=new char[10] {'A','B','C','D','F','G','H','J','K','L'};
int currentQNo; //current question number
int totalQNumber; // total quiz question number
int totalMarkedQuestion; // total marked questions number
    int currentMarkedQuestion; //current bookmarked question number
    int markLoop; // the res number of reanswered bookmarked questions
DateTime startTime; // quiz start time
TimeSpan spentTime;
bool isReview; // to indicate the status of current qustion
bool wasChecked=false; //signed as marked Q within Review report.

In the page_load(....), do the following:

C#
private void Page_Load(object sender, System.EventArgs e)
{
    //load our XML DB
    doc.Load(Server.MapPath("quiz.xml"));
    //create navigator for loaded xml File
    nav=doc.CreateNavigator();

    //Is New Quiz?.
    if(!IsPostBack)
    {
        //Yes.
        quizPanal.Visible=true;// show quiz screen.

        //record start time
        startTime=DateTime.Now;
        currentQNo=1;
        //count and record Total questions Number
        //using our XmlDocumentnavigator by passing
        //XPath sring of question node ( <mc>...</mc>)
            totalQNumber=nav.Select("//mc").Count;
            //store our data in Session bag
            //simply,I use the same name for Sessionbag object
            //and member Field..
        ViewState["startTime"]=startTime;
        ViewState["totalQNumber"]=totalQNumber;
        ViewState["currentQNo"]=currentQNo;
        ViewState["score"]=0;
        //go to first Question
        ShowQuestion(currentQNo);
        }
    }

Let's render question number as currentQNo : ShowQuestion(currentQNo);

Render a specific multi-choice question. This method takes question number as parameter, and uses this number within different XPath strings to navigate through our XML nodes:

C#
/// <summary>
/// Retrive Question and its Choices from
/// XML file and render it to screen
/// </summary>
/// <param name="_qNo">Question Numberv/param>
public void ShowQuestion(int _qNo)
{
    quizPanal.Visible=true;

    //clear any selected radioList item
    answersRBL.Items.Clear();
    //retrieve Data from session bag and calculate spent time
    startTime=(DateTime)ViewState["startTime"];
    totalQNumber=Convert.ToInt32(ViewState["totalQNumber"]);
    spentTime=DateTime.Now.Subtract(startTime);
    //XPath String of current question node
    //quiz/mc[current question number]
    string xPath="quiz/mc["+_qNo.ToString()+"]";

    int counter=1;
    string str;
    //read current Q Text by by using Select() method
    //of our navigator by set the XPath string
    //as address of current Question text Node:
    //quiz/mc[current question number]/question
    nodeItrator=nav.Select(xPath+"/question");
    nodeItrator.MoveNext();
    //display some data
    qNoLbl.Text="Q: "+_qNo.ToString()+" / "+totalQNumber.ToString();
    questionLbl.Text=_qNo.ToString()+": "+nodeItrator.Current.Value;
    spentTimeLbl.Text=spentTime.Minutes.ToString()
               +"~"+spentTime.Seconds.ToString();

    //answer nodes Xpath string quiz/mc[current question number]/answer
    nodeItrator=nav.Select(xPath+"/answer");

    while(nodeItrator.MoveNext())
    {
        str=counter.ToString();
        //add  new radioBtn to Answers RadioList with perfix A, B..
        //with text o the current text node
        answersRBL.Items.Add(new ListItem(perfix[counter-1].ToString()
                       +":"+nodeItrator.Current.Value,str));

        //keep correct answer in mind
        if(nodeItrator.Current.GetAttribute("correct","")=="Yes")
        {
            ViewState["correctAnswer"]=counter;
        }
        counter++;//next
    }

There are some actions that take place when this method renders bookmarked questions:

C#
    //retrieve current status from session bag
    isReview=Convert.ToBoolean(ViewState["isReview"]);
    //Is Review Bookmarked questions Only?
    if(isReview)
    {//yes
        //disable bookmark checkbox
        bookmarkCKBX.Enabled=false;
        //dispaly an image to notify user
        Image1.Visible=true;
        qNoLbl.ForeColor=Color.Red;
        RequiredFieldValidator1.Text="Answer The Question !";
    }
    currentQNo++;//next
    ViewState["currentQNo"]=currentQNo;
}//end method

After that, the user reviews answers history and is allowed to go back or view score report Review():

C#
/// <summary>
/// generate Review Report
/// by retrive user answers from historyALst ArrayList
/// and Bookmarked Question(s) from bookmarkLst ArrayList
/// and do user descion
/// </summary>
public void Review()
{
    revisionPanal.Visible=true;

    int seqance=0;
    string _is="No";
    //retrieve marked Questions and answers List
    bookmarkLst=(ArrayList)ViewState["bookmarkLst"];
    historyALst=(ArrayList)ViewState["historyALst"];
    totalQNumber=Convert.ToInt32(ViewState["totalQNumber"]);

    wasChecked=Convert.ToBoolean(ViewState["wasChecked"]);
    //are you marked some questions for review ?
    if(!wasChecked){ /* No */ markBtn.Enabled=false;}

    //create Answers History report
    //
    //table header
    TableCell c=new TableCell();
    TableCell cc=new TableCell();
    TableCell ccc=new TableCell();

    c.Text="Question No.";
    cc.Text="Your Answer";
    ccc.Text="Bookmark ?";

    TableRow hr=new TableRow();
    hr.Cells.Add(c);
    hr.Cells.Add(cc);
    hr.Cells.Add(ccc);

    hr.ForeColor=Color.White;
    hr.BackColor=Color.LightSlateGray;

    Table1.Rows.Add(hr);

    Table1.Font.Bold=true;
    //your records
    for(int i=1;i<=totalQNumber;i++)
    {
        //Cell: Q Number
        TableCell c1=new TableCell();
        c1.Text=i.ToString();
        //Cell: your answer A,B, or C...
        TableCell c2=new TableCell();
        c2.HorizontalAlign=HorizontalAlign.Center;
        c2.Text=perfix[Convert.ToInt32(historyALst[i-1])-1].ToString();
        //Cell: bookmarked or not
        TableCell c3=new TableCell();
        for(int n=0;n < bookmarkLst.Count;n++)
        {    //Is this Q bookmarked ?
            if(Convert.ToInt32(bookmarkLst[n].ToString())==i)
            {//Yes
                _is=" Yes ";
            }
        }

        c3.Text=_is;
        c3.HorizontalAlign=HorizontalAlign.Center;//align=center
        _is=" No ";//Re-Assign
        TableRow r=new TableRow();
        r.Cells.Add(c1);
        r.Cells.Add(c2);
        r.Cells.Add(c3);
        r.ForeColor=Color.SlateGray;
        //
        //Just, Table template
        if(seqance % 2 != 0)
        {
            r.BackColor=Color.Gainsboro;
        }

        //display it
        Table1.Rows.Add(r);

        eqance++;//next ..
    }//end for
}//end method

If the user decides to go back, then ReAnswer():

C#
/// <summary>
/// generate a list of bookmarked questions
/// and fire ShowQuestion() for first one
/// according to some rules
/// </summary>
public void ReAnswer()
{
    quizPanal.Visible=true;

    isReview=true;
    //retrieve data
    bookmarkLst=(ArrayList)ViewState["bookmarkLst"];

    totalMarkedQuestion=bookmarkLst.Count;
    currentMarkedQuestion=Convert.ToInt32(bookmarkLst[0]);
    //store data
    markLoop=1;
    ViewState["markLoop"]=markLoop;
    ViewState["isReview"]=isReview;
    ViewState["totalMarkedQuestion"]=totalMarkedQuestion;
    ViewState["currentMarkedQuestion"]=currentMarkedQuestion;
    //Show first marked question
    ShowQuestion(currentMarkedQuestion);
}//end method

In the end, call the Score report: ShowResult()

C#
/// <summary>
/// generate Score Report
/// by some simple calculations
/// </summary>
public void ShowResult()
{
    resultPanal.Visible=true;
    //retrieve data
    int score=Convert.ToInt32(ViewState["score"]);
    totalQNumber=Convert.ToInt32(ViewState["totalQNumber"]);
    startTime=(DateTime)ViewState["startTime"];
    spentTime=DateTime.Now.Subtract(startTime);

    //set own Progress Bar Max. Value
    progressBar.Total=totalQNumber*100;
    //set your score as progressed value
    progressBar.Value=score*100;

    //display some data:
    //
    //date
    dateLbl.Text=DateTime.Now.ToUniversalTime().ToShortDateString();
    //total Q number
    totalQNoREsLbl.Text=totalQNumber.ToString();
    //Total Score (as Total Question number * 100 )
    totalScoreLbl.Text=(totalQNumber*100).ToString();
    //Your Score (as your correct answers * 100)
    scoreLbl.Text=(score*100).ToString();
    //number of correct answers
    correctAnswersLbl.Text=score.ToString();
    //passing score
    passingScoreLbl.Text=(totalQNumber*100/2).ToString();
    //Time Spent
    timeTakenLbl.Text=spentTime.Hours.ToString()
            +"<font color=\"#666699\">:</font>"
            +spentTime.Minutes.ToString()
            +"<font color=\"#666699\">:</font>"
            +spentTime.Seconds.ToString()
            +"<font color=\"#666699\" size=\"1\">Hr(s).</font>";


    //Success or ...!
    if((score*100/totalQNumber)<50)
    {
        gradeLbl.ForeColor=Color.Red;
        gradeLbl.Text="Failed";
    }
    else
    {
        gradeLbl.ForeColor=Color.Green;
        gradeLbl.Text="Success";
    }
}//end method

Done ..........!

License

This article, along with any associated source code and files, is licensed under The Microsoft Public License (Ms-PL)


Written By
Team Leader
United Arab Emirates United Arab Emirates
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionIn Review How to Display Correct Answer Pin
sabaaqeel7-Apr-14 2:49
sabaaqeel7-Apr-14 2:49 
QuestionHow to run your application? Pin
megha_gharote17-Jun-09 17:38
megha_gharote17-Jun-09 17:38 
AnswerRe: How to run your application? Pin
sandeepknrohan4-Jul-11 18:36
sandeepknrohan4-Jul-11 18:36 
Hi,

Were you able to run this?
QuestionHelp needed Pin
P.K.Pattnaik15-May-07 0:25
P.K.Pattnaik15-May-07 0:25 
Questionhow to see the codes in action ? Pin
arunbiswas16-Feb-07 21:03
arunbiswas16-Feb-07 21:03 
GeneralA Great Start Pin
John Jasper15-Jul-06 6:26
John Jasper15-Jul-06 6:26 
GeneralThank You! Pin
ohyeahbaby2-Aug-05 7:33
ohyeahbaby2-Aug-05 7:33 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.