【问题标题】:Looping through quiz questions fails循环测验问题失败
【发布时间】:2014-06-10 20:07:58
【问题描述】:

已编辑 - 我最初发布了我的代码的早期版本,现在下面是正确的代码

我有一个测验问题的数据库表,我在我的表单中显示,但是,当我到达表中的最后一个问题时,我收到以下错误:

IndexOutOfRangeException was unhandled
There is no row at position 5

我的表结构是这样的:

问题编号 |问题 |答案 1 |答案 2 |答案 3 |答案 4 |正确答案

这是我的代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.OleDb;
using System.Data.SqlClient;

namespace WindowsFormsApplication1
{
public partial class QuizQuestions : Form
{
    public WindowsAnalysisQuiz()
    {
        InitializeComponent();
    }
    //int questionNumber;
    String correctAnswer;
    private void WindowsAnalysisQuiz_Load(object sender, EventArgs e)
    {
        //declare connection string using windows security
        string cnString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\Users\\Hanna\\Desktop\\QuizQuestions.accdb";

        //declare Connection, command and other related objects
        OleDbConnection conGet = new OleDbConnection(cnString);
        OleDbCommand cmdGet = new OleDbCommand();

        //try
        //{
        //open connection
        conGet.Open();
        //String correctAnswer;

        cmdGet.CommandType = CommandType.Text;
        cmdGet.Connection = conGet;

        cmdGet.CommandText = "SELECT * FROM QuizQuestions ORDER BY rnd()"; 

        OleDbDataReader reader = cmdGet.ExecuteReader();

        reader.Read();
        label1.Text = reader["Question"].ToString();
        radioButton1.Text = reader["Answer 1"].ToString(); 
        radioButton2.Text = reader["Answer 2"].ToString();
        radioButton3.Text = reader["Answer 3"].ToString();
        radioButton4.Text = reader["Answer 4"].ToString();
        correctAnswer = reader["Correct Answer"].ToString();
        //questionNumber = 0;

        conGet.Close();

    }

    private void btnNextQuestion_Click(object sender, EventArgs e)
    {

        String cnString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\Users\\Hannah\\Desktop\\QuizQuestions.accdb";
        int questionNumber = 0;
        //declare Connection, command and other related objects
        OleDbConnection conGet = new OleDbConnection(cnString);
        OleDbCommand cmdGet = new OleDbCommand();

        //try
        {
            //open connection
            conGet.Open();

            cmdGet.CommandType = CommandType.Text;
            cmdGet.Connection = conGet;

            cmdGet.CommandText = "SELECT * FROM QuizQuestions ORDER BY rnd()"; // select all columns in all rows

            OleDbDataReader reader = cmdGet.ExecuteReader();
            reader.Read();

            String chosenAnswer = "";
            //int chosenCorrectly = 0;
            if (radioButton1.Checked)
            {
                chosenAnswer = reader["Answer 1"].ToString();
            }
            else if (radioButton2.Checked)
            {
                chosenAnswer = reader["Answer 2"].ToString();
            }
            else if (radioButton3.Checked)
            {
                chosenAnswer = reader["Answer 3"].ToString();
            }
            else
            {
                chosenAnswer = reader["Answer 4"].ToString();
            }

            if (chosenAnswer == reader["Correct Answer"].ToString())
            {
                labelQuestion.Text = table.Rows[questionNumber]["Question"].ToString();
                //and show possible answers:
                radioButton1.Text = table.Rows[questionNumber]["Answer 1"].ToString();
                radioButton2.Text = table.Rows[questionNumber]["Answer 2"].ToString();
                radioButton3.Text = table.Rows[questionNumber]["Answer 3"].ToString();
                radioButton4.Text = table.Rows[questionNumber]["Answer 4"].ToString();
                correctAnswer = table.Rows[questionNumber]["Correct Answer"].ToString();
                questionNumber++; //got to next question! 
            }
            else
            {
                MessageBox.Show("That is not the correct answer");
            }
        }

    }
}

}

我要做的是获得一个 for 循环,该循环将列出我数据库中的问题,但在最后一个问题得到回答时,我可以将所有正确回答的答案加起来,当然,没有得到我得到的错误

【问题讨论】:

  • 这个代码复制字符串中有很多不好的编码实践,应该是本地的实例变量,对 OldDbX...X 对象的凌乱隐含处置...

标签: c# winforms


【解决方案1】:

我认为questionNumber 的起始值需要为 0,因为 Rows 从零开始,否则 table.Rows[questionNumber] 将在最后一行失败。

【讨论】:

  • 另外,questionNumber 是没有限制的,所以每次按下按钮时都会增加 questionNumber。除非你没有展示所有的代码。
【解决方案2】:

您应该将 questionNumber 初始值设置为 0,因为行数为零。并获取 pageload 中问题的计数并将其设置为另一个变量 int questionCount 您可以在 buttonClick 中访问它。

在 buttonClick 中将 questionNumber++ 更改为 questionNumber= (questionNumber++%questionCount);

问题做完后会回到开头。

希望这会有所帮助。

【讨论】:

    【解决方案3】:

    每次选择正确答案时,您在 btnGoToNextOne_Click 中的代码都会无条件地递增 questionNumber (questionNumber++)。正确选择最后一个问题后,questionNumber 索引超出范围,因此可能是代码中其他地方的问题。

    另一件事是,在 Form1_Load 中,您设置了 questionNumber = 1,它假定您的数据库中至少有 2 个问题。除非您出于某种原因将 questionNumber 设置为 1,否则它可能应该设置为 0(因为 C# 中的索引是从零开始的)。

    您在此代码中执行操作的方式还有很多不足之处,重复​​字符串,OleDbX...X 对象应该包装在 using(OleDbX...X) {} 中,以便处理它们适当地;为什么DataTable表不是局部变量,我不知道...

    【讨论】:

      【解决方案4】:

      如果这是最后一行,你应该告诉编译器结束,即你应该添加这个..

      if (chosenAnswer == reader["Correct Answer"].ToString() && 
          questionNumber <= tables[your table].rows.count()) 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-07-16
        • 1970-01-01
        • 1970-01-01
        • 2020-07-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多