Click here to Skip to main content
Click here to Skip to main content

Integrated Quiz WebApp with Graphical Score Report

By , 21 May 2005
Rate this:
Please Sign up or sign in to vote.

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 version="1.0" encoding="utf-8" ?> 
<quiz>
  <mc>
     <question correctAnsNo='1'>Which of the fol....?
     </question>
     <answer correct='No' ><![CDATA[<span class="code-SummaryComment">  <img src="x...]]></span>
     </answer>
     <answer correct='No' ><![CDATA[<span class="code-SummaryComment">  <img src="x...]]></span>
     </answer>
     <answer correct='Yes'><![CDATA[<span class="code-SummaryComment">  <img src="x...]]></span>
     </answer>
     <answer correct='No' ><![CDATA[<span class="code-SummaryComment">  I Don't Know  ]]></span>
     </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:

    //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:

    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:

    /// <span class="code-SummaryComment"><summary>
</span>
    /// Retrive Question and its Choices from
    /// XML file and render it to screen
    /// <span class="code-SummaryComment"></summary>
</span>
    /// <span class="code-SummaryComment"><param name="_qNo">Question Numberv/param>

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

        //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():

    /// <span class="code-SummaryComment"><summary>
</span>
    /// generate Review Report
    /// by retrive user answers from historyALst ArrayList
    /// and Bookmarked Question(s) from bookmarkLst ArrayList
    /// and do user descion
    /// <span class="code-SummaryComment"></summary>
</span>
    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():

    /// <span class="code-SummaryComment"><summary>
</span>
    /// generate a list of bookmarked questions
    /// and fire ShowQuestion() for first one
    /// according to some rules
    /// <span class="code-SummaryComment"></summary>
</span>
    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()

    /// <span class="code-SummaryComment"><summary>
</span>
    /// generate Score Report
    /// by some simple calculations
    /// <span class="code-SummaryComment"></summary>
</span>
    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)

About the Author

Ameen Abudbash
Team Leader
Egypt Egypt
• Over 8 years of experience in software developing, designing and implementing High Available web based applications specialized in Microsoft & IBM technologies.
• Extensive experience in developing, designing and implementing ECM solutions using IBM Filenet,Workplace, IBM BPM, REST services, AND Partial Experience in major CMS (Documentum and Oracle ECM).
• Extensive experience in Designing & Implementing Web2 Enterprise Apps using Leading RIA Frameworks (ExtJs , YUI… ).
• Partial experience in development with Microsoft SharePoint 2007 & 2010.
• Practical experience in Microsoft BI tools SSAS, SSIS, SSRS and Excel Services.
• Deep understanding of the OOP and Strong Design patterns background
• Interactive and fast enough to learn new technologies and sciences.
 
• Extensive experience in problem-to-resolution troubleshooting skills
• Playing different IT roles including designing, implementing, supporting, consulting and development, Managing teams composed of analyst, developers & QA.
• Agile project management methodologies and managed teams with Scrum.
• Deliver technical workshops, presentations, documents and POCs.
Follow on   Twitter   Google+

Comments and Discussions

 
Questionhow to see the codes in action ? Pinmemberarunbiswas16-Feb-07 21:03 

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

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

| Advertise | Privacy | Mobile
Web02 | 2.8.140415.2 | Last Updated 21 May 2005
Article Copyright 2005 by Ameen Abudbash
Everything else Copyright © CodeProject, 1999-2014
Terms of Use
Layout: fixed | fluid