使用 asp.net C# 和数据库计算测验分数

Calculating score on a quiz test using asp.net C# with database

我正在尝试使用数据库在 asp.net C# 中的 Web 应用程序中创建测验。小测验有25个问题和5个答案,每个答案都有分数(完全同意(1),同意(2),不确定(3),不同意(4),完全不同意(5))。

问题和答案在数据库中。 我想要的是当我单击提交按钮以计算这些问题的分数并将分数放入我的数据库中的 table 中时。 我尝试做一个 if (radiobutton1.checked){ 分数=2} 但它不起作用,因为中继器......我想我不确定。 我尝试删除转发器,但当我这样做时,网页上没有显示问题和答案。

在我的 aspx 文件中,我编写了代码来显示来自数据库的数据(使用转发器和 table):

  <asp:Repeater ID="Repeater1" runat="server">
<ItemTemplate>
    <table>
        <tr>
            <td> <%#Eval("IDq") %> )  <%#Eval("qustion") %></td></tr>
        <tr>
            <td>
                <asp:RadioButton ID="RadioButton1" runat="server" Text='<%#Eval("ans1")%>' GroupName="quiz" Value="1"></asp:RadioButton>
                <asp:RadioButton ID="RadioButton2" runat="server" Text='<%#Eval("ans2") %>' GroupName="quiz" Value="2"></asp:RadioButton>
                <asp:RadioButton ID="RadioButton3" runat="server" Text='<%#Eval("an3") %>' GroupName="quiz" Value="3"></asp:RadioButton>
                <asp:RadioButton ID="RadioButton4" runat="server" Text='<%#Eval("ans4") %>' GroupName="quiz" Value="4"></asp:RadioButton>
                <asp:RadioButton ID="RadioButton5" runat="server" Text='<%#Eval("ans5") %>' GroupName="quiz" Value="5"></asp:RadioButton>
                <br />
            </td>
        </tr> </table>
</ItemTemplate></asp:Repeater>

好的,你有一个好的开始。

我要建议用它代替 RadioGroup 标签?

那确实让你自动只有一个选择。问题是我们仍然必须检查所有 5 个控件。

在这种情况下,更好的控件是使用所谓的 RadioButtonList。它的工作原理与使用 RadioGroup 非常相似,但真正好的部分是什么?

为ONE控件,如果Radio button group有3个或15个选择,则为ONE控件returns

the index of the selection (0 to N)
the text value of the selection
the value value of the selection.

所以我建议使用 RadioButton 列表 - 因为 returns 选择是“一回事”。

RadioButtonList 的“主要”问题是您不能像您现在使用的那样使用那些很酷的数据绑定表达式(这对您来说很好call/design)。

但是,要么我们写一个循环到“get/check”5 个 raido 按钮,要么我们写一个循环来填充 Radiobutton 列表 - 我认为使用代码来填充 RadioButton 列表是更好的选择.

此外,你是新手 - 我看到你正在尝试使用一些 "table 和 "tr" 来帮助你布置东西。你真的不需要这个。

现在,因为以上所有想法为我们节省了很多时间和代码?好吧,那么我们可以添加额外的代码说

 show the score and results after we submit
 tell the user they did NOT answer a question - they MUST!!!
 heck, toss is a cool check box, or X box to show wrong or right.
 Allow a question to only have say 2 answers - not always all 5

好的,首先,我们的 table - 它看起来像这样:

所以,我们有了 IDq(问题的 id)。 1 到 5 个可能的答案,然后是包含正确答案的列。

好的,现在是我们的标记。正如我所说,由于我们减少了如此多的标记和代码,所以我添加了当用户未回答所有问题时显示的粗体红色消息。

我还添加了一个“结果”框,在您点击提交时显示(数字错误,正确)。

所以,现在我们的 Markup 变成了这样:

    <div style="width:35%">
        <asp:Repeater ID="Repeater1" runat="server">
        <ItemTemplate>
            <div style="float:left">
            <asp:Label ID="Question" runat="server" 
                Text = '<%# Eval("IDq").ToString + " ) " + Eval("question") %>' 
                Font-Size="X-Large">
            </asp:Label>
            </div>
            <div style="float:right">
                <img id="MyImage" runat="server" src="" height="48" width="48" />
            </div>
            <div style="clear:both">

            <asp:RadioButtonList ID="RadioButtonList1" runat="server" RepeatDirection="Horizontal" ></asp:RadioButtonList>
            </div>
            <br />
            <hr></hr>
        </ItemTemplate>
      </asp:Repeater>

        <asp:Button ID="cmdDone" runat="server" Text="Submit" />

        <div id="MyError" style="display:none;normal;color:red" runat="server">
            <h2>You have not answered all questions</h2>
            <h2>Please answer all questions before submitting</h2>
        </div>

        <div id="Results" runat="server" style="clear:both; display:none" >
            <h2>Results</h2>
            <asp:TextBox ID="MyCorrect" runat="server"></asp:TextBox>
            <br />
            <asp:TextBox ID="InCorrect" runat="server"></asp:TextBox>
        </div>

    </div>

因此,没有太多标记 - 我们添加了相当多的新功能。

我还提出了显示正确和错误复选框的想法 - 您可以删除该部分 - 但它确实可以帮助您在这里学到很多东西。

所以,现在当我 运行 代码时,我看到了这个:

所以注意我答对的问题。正如我所说 - 您可能希望删除它。

请注意我尚未回答所有问题的消息。

因此,如前所述,我们有更多的代码来加载 Repeater,但之后检查的代码更少。

所以,我们的代码现在看起来像这样:

private DataTable MyTable = new DataTable();

protected void Page_Load(object sender, System.EventArgs e)
{
    if (IsPostBack == false)
    {
        LoadData();
        ViewState["MyTable"] = MyTable;
    }
    else
        MyTable = ViewState["MyTable"];
}

public void LoadData()
{
    using (SqlCommand cmdSQL = new SqlCommand("SELECT * from tblQuestions ORDER BY IDq",
                             new SqlConnection(My.Settings.TEST4)))
    {
        cmdSQL.Connection.Open();
        MyTable.Load(cmdSQL.ExecuteReader);
        Repeater1.DataSource = MyTable;
        Repeater1.DataBind();
    }
}

protected void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
    if (e.Item.ItemType == ListItemType.Item | e.Item.ItemType == ListItemType.AlternatingItem)
    {
        DataRow MyRow = MyTable.Rows(e.Item.ItemIndex);

        RadioButtonList rBtnList = e.Item.FindControl("RadioButtonList1");
        for (var i = 1; i <= 5; i++)
        {
            var strR = "ans" + i;
            if (IsDBNull(MyRow(strR)) == false)
            {
                ListItem nItem = new ListItem(MyRow(strR), i);
                rBtnList.Items.Add(nItem);
            }
        }
    }
}

protected void cmdDone_Click(object sender, EventArgs e)
{

    // check all rows - make sure all have a answer
    // show check box for correct answers
    // total up correct answers (count)
    // total up wrong answers (count)

    MyError.Style("Display") = "none";


    int Correct = 0;
    int Wrong = 0;
    int NotAnser = 0;

    foreach (RepeaterItem ritem in Repeater1.Items)
    {
        RadioButtonList RadioBut = ritem.FindControl("RadioButtonList1");

        if (RadioBut.SelectedIndex >= 0)
        {
            HtmlImage MyImage = ritem.FindControl("MyImage");
            if (MyTable.Rows(ritem.ItemIndex).Item("Answer") == RadioBut.SelectedIndex + 1)
            {
                Correct += 1;
                MyImage.Src = "/Content/ok.png";
            }
            else
            {
                Wrong += 1;
                MyImage.Src = "/Content/reject.png";
            }
        }
        else
        {
            NotAnser += 1;
        }
    }

    // if missed questions then display warning.

    if (NotAnser > 0)
        MyError.Style("Display") = "normal";
    else
    {
        MyCorrect.Text = "Correct answers = " + Correct;
        InCorrect.Text = "Wrong answers = " + Wrong;
        Results.Style("Display") = "normal";
    }
}

所以你可以在那个提交按钮代码中看到,我们现在很容易循环转发器,得到用户答案,检查 table 数据。

请注意另一个技巧 - 我将 MyTable 持久化到 ViewState 中。我这样做是因为我不想每次都重新加载 table - 它只是意味着任何按钮点击、控制和代码隐藏?我总是手边有数据 table

现在,考虑到上面的答案总和,那么您将不得不再添加 2-5 行代码来写出总数或结果 - 如果您打算有一些其他 table 你说了一些学生 ID 或用户 ID,然后你保存了测试的总结果(或正确计数,或错误计数)。

所以,最后的结果是这样的: