开发实践教程1:试卷生成系统6.6 考题(FormExamSingle)

Posted VB.Net

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了开发实践教程1:试卷生成系统6.6 考题(FormExamSingle)相关的知识,希望对你有一定的参考价值。

版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的。

增加、修改或查看考题。

窗体设计如下:

图1-16

考虑到考题中可能出现图片,需要将图片也保存到数据库。代码中使用saveImg()方法来保存、更新或删除图片。由于保存图片时二进制操作可能涉及到的数据比较大,因此这里增加了对图片是否修改的判断,如果修改或新增了,那么才调用图片保存的语句。关于保存图片数据到数据库,请参看教程第19.4.6节《读写二进制数据》

具体代码如下:

Imports System.Data.SqlClient
Imports System.IO

Public Class FormExamSingle

    Dim examId As Integer

    Dim connection As SqlConnection

    Dim isEditExam As Boolean = False

    Dim lstExamType As New List(Of Integer)

    Dim lstTestPaperTypeB As New List(Of Integer)
    Dim lstTestPaperTypeM As New List(Of Integer)
    Dim lstTestPaperTypeS As New List(Of Integer)

    Dim hasEdit As Boolean

    Dim imgID As Integer = 0
    Dim hasImgEdit As Boolean
    Dim imgFile As String

    Enum OptionState
        add = 0       '新增
        edit = 1        '编辑
        onlysee = 2     '仅查看
    End Enum

    Dim State As OptionState

    Public Sub New(ByVal examId As Integer, ByVal state As OptionState)

        InitializeComponent()

        Me.examId = examId
        Me.State = state

    End Sub

    Private Sub FormExamSingle_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        connection = New SqlConnection(databaseConnString)
        connection.Open()

        Call drawComboBox()

        Select Case State
            Case OptionState.add

            Case OptionState.edit
                Call drawUI()

            Case OptionState.onlysee
                Call drawUI()
                cmsPb.Enabled = False
                btnOk.Visible = False

        End Select

    End Sub


    Private Sub drawComboBox()
        Dim sql As String
        sql = "select 编号,类型名称 from 考试类型表一级"

        Dim command As New SqlCommand()

        command.CommandText = sql
        command.Connection = connection

        Dim sqlReader As SqlDataReader
        sqlReader = command.ExecuteReader()

        If sqlReader.HasRows Then
            Do While sqlReader.Read
                cbPaperTypeB.Items.Add(sqlReader.GetString(1))
                lstTestPaperTypeB.Add(sqlReader.GetInt32(0))
            Loop
        End If
        sqlReader.Close()
        If cbPaperTypeB.Items.Count > 0 Then cbPaperTypeB.SelectedIndex = 0

        sql = "select 编号,类型名称 from 题类型表"
        command.CommandText = sql
        sqlReader = command.ExecuteReader()
        If sqlReader.HasRows Then
            Do While sqlReader.Read
                cbType.Items.Add(sqlReader.GetString(1))
                lstExamType.Add(sqlReader.GetInt32(0))
            Loop
        End If
        sqlReader.Close()
        If cbType.Items.Count > 0 Then cbType.SelectedIndex = 0

    End Sub

    Private Sub drawUI()
        Dim title As String
        Dim examType As Integer
        Dim paperTypeB As Integer
        Dim paperTypeM As Integer
        Dim paperTypeS As Integer
        Dim examOption As String
        Dim examAnswer As String



        Dim sql As String
        sql = "SELECT 题表.题类型, 题表.题目, 题表.图片, 题表.选项, 题表.答案, 题表.考试类型, 考试类型表二级.编号, 考试类型表一级.编号 " &
              "FROM 题表 INNER JOIN ((考试类型表三级 INNER JOIN 考试类型表二级 ON 考试类型表三级.二级类型 = 考试类型表二级.编号) INNER JOIN 考试类型表一级 ON 考试类型表二级.一级类型 = 考试类型表一级.编号) ON 题表.考试类型 = 考试类型表三级.编号 " &
              "where 题表.编号=" & examId

        Dim command As New SqlCommand()

        command.CommandText = sql
        command.Connection = connection

        Dim sqlReader As SqlDataReader
        sqlReader = command.ExecuteReader()

        If sqlReader.HasRows Then
            sqlReader.Read()
            examtype = sqlReader(0)
            title = sqlReader(1)
            imgID = sqlReader(2)
            examOption = sqlReader(3)
            examAnswer = sqlReader(4)
            paperTypeS = sqlReader(5)
            paperTypeM = sqlReader(6)
            paperTypeB = sqlReader(7)

        Else
            Exit Sub
        End If
        sqlReader.Close()

        txtTitle.Text = title
        txtAnswer.Text = examAnswer
        cbType.SelectedIndex = lstExamType.IndexOf(examType)
        cbPaperTypeB.SelectedIndex = lstTestPaperTypeB.IndexOf(paperTypeB)
        cbPaperTypeM.SelectedIndex = lstTestPaperTypeM.IndexOf(paperTypeM)
        cbPaperTypeS.SelectedIndex = lstTestPaperTypeS.IndexOf(paperTypeS)

        If Not IsNothing(examOption) Then
            If examOption <> "" Then
                Dim separator() As String = {"@;@"}
                Dim examOptions() As String
                examOptions = examOption.Split(separator, StringSplitOptions.RemoveEmptyEntries)
                For i As Integer = 0 To examOptions.Length - 1
                    lbOption.Items.Add(examOptions(i))
                Next
            End If
        End If


        If imgID <> 0 Then
            command.CommandText = "select 图片数据 from 图表 where 编号=" & imgID
            Dim sqlReaderimg As SqlDataReader = command.ExecuteReader(CommandBehavior.SequentialAccess)
            Try
                Dim buffersize As Integer = 1024
                Dim buffer(buffersize - 1) As Byte

                Dim ms As New MemoryStream

                If sqlReaderimg.HasRows = False Then
                    MessageBox.Show("图片数据出错")
                    Exit Sub
                End If

                sqlReaderimg.Read()

                Dim returnbyte As Integer
                Dim startpos As Integer = 0
                returnbyte = sqlReaderimg.GetBytes(0, startpos * buffersize, buffer, 0, buffersize)
                Do While returnbyte = buffersize
                    ms.Write(buffer, 0, buffersize)
                    ms.Flush()

                    ReDim buffer(buffersize - 1)
                    startpos += 1
                    returnbyte = sqlReaderimg.GetBytes(0, startpos * buffersize, buffer, 0, buffersize)
                Loop

                pbImg.Image = Image.FromStream(ms)

            Catch ex As Exception
                MessageBox.Show("载入图片出现错误!")
            End Try
        End If

    End Sub

    Private Sub cbPaperTypeB_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cbPaperTypeB.SelectedIndexChanged
        cbPaperTypeM.Items.Clear()
        lstTestPaperTypeM.Clear()
        cbPaperTypeS.Items.Clear()
        lstTestPaperTypeS.Clear()

        Dim paperTypeBIndex As Integer = cbPaperTypeB.SelectedIndex

        Dim sql As String
        sql = "select 编号,类型名称 from 考试类型表二级 where 一级类型=" & lstTestPaperTypeB(paperTypeBIndex)


        Dim command As New SqlCommand()

        command.CommandText = sql
        command.Connection = connection

        Dim sqlReader As SqlDataReader
        sqlReader = command.ExecuteReader()

        If sqlReader.HasRows Then
            Do While sqlReader.Read
                cbPaperTypeM.Items.Add(sqlReader(1))
                lstTestPaperTypeM.Add(sqlReader(0))
            Loop
        End If

        sqlReader.Close()

        If cbPaperTypeM.Items.Count > 0 Then cbPaperTypeM.SelectedIndex = 0
    End Sub

    Private Sub cbPaperTypeM_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cbPaperTypeM.SelectedIndexChanged
        cbPaperTypeS.Items.Clear()
        lstTestPaperTypeS.Clear()

        Dim paperTypeMIndex As Integer = cbPaperTypeM.SelectedIndex

        Dim sql As String
        sql = "select 编号,类型名称 from 考试类型表三级 where 二级类型=" & lstTestPaperTypeM(paperTypeMIndex)

        Dim command As New SqlCommand()

        command.CommandText = sql
        command.Connection = connection

        Dim sqlReader As SqlDataReader
        sqlReader = command.ExecuteReader()

        If sqlReader.HasRows Then
            Do While sqlReader.Read
                cbPaperTypeS.Items.Add(sqlReader(1))
                lstTestPaperTypeS.Add(sqlReader(0))
            Loop
        End If

        sqlReader.Close()

        If cbPaperTypeS.Items.Count > 0 Then cbPaperTypeS.SelectedIndex = 0
    End Sub

    Private Sub btnOk_Click(sender As Object, e As EventArgs) Handles btnOk.Click
        Dim errMsg As String = checkData()
        If errMsg <> "" Then
            MessageBox.Show(errMsg)
            Exit Sub
        End If

        Dim imgNewId As Integer
        If hasImgEdit = True Then
            imgNewId = saveImg(imgID)
            If imgNewId = -1 Then
                MessageBox.Show("保存图片时发生错误")
                Exit Sub
            End If
        End If

        errMsg = saveExam(imgNewId)
        If errMsg <> "" Then
            MessageBox.Show(errMsg)
            Exit Sub
        End If

        Me.Close()
    End Sub

    Private Function saveImg(ByVal imgId As Integer) As Integer

        Dim command As New SqlCommand()
        command.Connection = connection

        Select Case State
            Case OptionState.add        '新增
                If IsNothing(pbImg.Image) = True Then
                    Return 0
                Else
                    Return saveNewImg()
                End If

            Case OptionState.edit       '修改
                If imgId = 0 Then
                    If IsNothing(pbImg.Image) = True Then
                        Return 0
                    Else
                        Return saveNewImg()
                    End If

                Else
                    If IsNothing(pbImg.Image) = True Then
                        command.CommandText = "delete * from 图表 where 编号=" & imgId
                        command.ExecuteNonQuery()
                        command.CommandText = "update 题表 set 图片=0 where 编号=" & examId
                        command.ExecuteNonQuery()
                        Return 0
                    Else
                        Dim imgData() As Byte
                        imgData = getImgData()

                        command.CommandText = "update 图表 set 图片数据=@imgData where 编号=" & imgId
                        command.Parameters.Add("@imgData", SqlDbType.Image, imgData.Length).Value = imgData
                        command.ExecuteNonQuery()
                        Return imgId
                    End If
                End If

            Case OptionState.onlysee
        End Select

    End Function

    Private Function saveNewImg() As Integer
        Dim command As New SqlCommand()
        command.Connection = connection


        Dim imgData() As Byte
        imgData = getImgData()

        Command.CommandText = "insert into 图表(图片数据) values(@imgData)"
        Command.Parameters.Add("@imgData", SqlDbType.Image, imgData.Length).Value = imgData
        Command.ExecuteNonQuery()

        Command.CommandText = "select top 1 编号 from 图表 order by 编号 desc"
        Dim sqlreader As SqlDataReader = Command.ExecuteReader(CommandBehavior.SingleResult)
        Dim imgNewId As Integer
        If sqlreader.HasRows Then
            sqlreader.Read()
            imgNewId = sqlreader(0)
            sqlreader.Close()
            Return imgNewId
        Else
            Return -1
        End If

    End Function

    Private Function getImgData() As Byte()
        Dim imgLenth As Integer
        Dim imgData() As Byte
        Dim fs As New FileStream(imgFile, FileMode.Open, FileAccess.Read)
        imgLenth = fs.Length
        ReDim imgData(imgLenth - 1)
        fs.Read(imgData, 0, imgLenth)
        fs.Close()

        Return imgData
    End Function

    Private Function checkData() As String
        If txtTitle.Text.Trim = "" Then
            Return "考题题目不能为空"
        End If

        If txtAnswer.Text.Trim = "" Then
            Return "考题答案不能为空"
        End If

        If (cbType.Text = "单选题") Or (cbType.Text = "多选题") Then
            If lbOption.Items.Count < 3 Then
                Return "选择题的选项应不低于3个"
            End If
        End If

        If cbPaperTypeS.Text = "" Then
            Return "必须选择第三级考试类型"
        End If

        Return ""
    End Function

    Private Function saveExam(ByVal imgId As Integer) As String
        Dim title As String
        Dim examType As Integer
        Dim paperTypeB As Integer
        Dim paperTypeM As Integer
        Dim paperTypeS As Integer
        Dim examOption As String = ""
        Dim examAnswer As String
        Dim recordTime As String = Now.ToString("yyyy-MM-dd HH:mm:ss")
        Dim isUse As String = "是"

        title = txtTitle.Text.Trim
        examType = lstExamType(cbType.SelectedIndex)
        paperTypeB = lstTestPaperTypeB(cbPaperTypeB.SelectedIndex)
        paperTypeM = lstTestPaperTypeM(cbPaperTypeM.SelectedIndex)
        paperTypeS = lstTestPaperTypeS(cbPaperTypeS.SelectedIndex)
        For i As Integer = 0 To lbOption.Items.Count - 1
            examOption &= lbOption.Items(i) & "@;@"
        Next
        If examOption.Length > 2 Then examOption = examOption.Substring(0, examOption.Length - 2)
        examAnswer = txtAnswer.Text.Trim

        Try
            Dim command As New SqlCommand()
            command.Connection = connection

            Select Case State
                Case OptionState.add
                    command.CommandText = "insert into 题表(题类型,题目,图片,选项,答案,考试类型,录入人ID,录入时间,是否启用) values('" &
                        examType & "','" & title & "'," & imgId & ",'" & examOption & "','" & examAnswer & "'," & paperTypeS & "," &
                        loginId & ",'" & recordTime & "','" & isUse & "')"

                Case OptionState.edit
                    command.CommandText = "update 题表 set 题类型='" & examType & "',题目='" & title & "',图片=" & imgId & ",选项='" & examOption & "',答案='" &
                        examAnswer & "',考试类型=" & paperTypeS & ",录入人ID=" & loginId & ",录入时间='" & recordTime &
                        "' where 编号=" & examId

                Case OptionState.onlysee

            End Select

            command.ExecuteNonQuery()

            Return ""
        Catch ex As Exception
            Return ex.Message
        End Try

    End Function

    Private Sub pbImg_DoubleClick(sender As Object, e As EventArgs) Handles pbImg.DoubleClick, tsmAdd.Click
        Dim filename As String
        Dim ofd As New OpenFileDialog
        ofd.Title = "选择图片"
        ofd.Filter = "图片文件|*.jpg;*.png"
        ofd.Multiselect = False
        If ofd.ShowDialog <> DialogResult.OK Then
            Exit Sub
        End If
        filename = ofd.FileName

        Dim maxFileSize As Integer = 1024 * 1024
        If New IO.FileInfo(filename).Length > maxFileSize Then
            MessageBox.Show("图片太大,请缩小后再添加")
            Exit Sub
        End If

        imgFile = filename
        pbImg.Image = Image.FromFile(filename)

        hasImgEdit = True
    End Sub
    Private Sub tsmClear_Click(sender As Object, e As EventArgs) Handles tsmClear.Click
        pbImg.Image = Nothing
        hasImgEdit = True
    End Sub
    Private Sub tsmSave_Click(sender As Object, e As EventArgs) Handles tsmSave.Click
        If IsNothing(pbImg.Image) = True Then
            Exit Sub
        End If
        Dim filename As String
        Dim sfd As New SaveFileDialog
        sfd.Title = "保存图片"
        sfd.Filter = "图片文件|*.jpg;*.png"
        If sfd.ShowDialog <> DialogResult.OK Then
            Exit Sub
        End If
        filename = sfd.FileName
        pbImg.Image.Save(filename)
    End Sub

    Private Sub tsmAddOption_Click(sender As Object, e As EventArgs) Handles tsmAddOption.Click
        If (cbType.Text <> "单选题") And (cbType.Text <> "多选题") Then
            MessageBox.Show("仅限选择题才提供选项")
            Exit Sub
        End If

        Dim examOption As String
        examOption = InputBox("请输入增加的选项内容")
        If examOption = "" Then Exit Sub
        lbOption.Items.Add(examOption)
    End Sub
    Private Sub tsmEditOption_Click(sender As Object, e As EventArgs) Handles tsmEditOption.Click
        If lbOption.SelectedIndex < 0 Then
            MessageBox.Show("请先选择一条记录")
            Exit Sub
        End If
        Dim pos As Integer = lbOption.SelectedIndex

        Dim examOption As String
        examOption = InputBox("请输入修改的内容")
        If examOption = "" Then Exit Sub
        lbOption.Items(pos) = examOption

    End Sub
    Private Sub tsmDelOption_Click(sender As Object, e As EventArgs) Handles tsmDelOption.Click
        If lbOption.SelectedIndex < 0 Then
            MessageBox.Show("请先选择一条记录")
            Exit Sub
        End If
        Dim pos As Integer = lbOption.SelectedIndex
        lbOption.Items.RemoveAt(pos)
    End Sub

    Private Sub btnClose_Click(sender As Object, e As EventArgs) Handles btnClose.Click
        Me.Close()
    End Sub


End Class

由于.net平台下C#和vb.NET很相似,本文也可以为C#爱好者提供的参考。

学习更多vb.net知识,请参看 vb.net 教程 目录

以上是关于开发实践教程1:试卷生成系统6.6 考题(FormExamSingle)的主要内容,如果未能解决你的问题,请参考以下文章

开发实践教程1:试卷生成系统6.5 考题搜索(FormExamQuery)

开发实践教程1:试卷生成系统6.15 考题类型管理(FormExamType)

开发实践教程1:试卷生成系统6.4 考题管理(FormExam)

开发实践教程1:试卷生成系统6.3 主界面(FormMain)

开发实践教程1:试卷生成系统6.8 试卷信息(FormTestPaperInfo)

开发实践教程1:试卷生成系统6.7 试卷生成(FormTestPaper)