翼度科技»论坛 编程开发 .net 查看内容

C#项目—模拟考试

7

主题

7

帖子

21

积分

新手上路

Rank: 1

积分
21
C#模拟考试软件

开发了一个《模拟考试》的小软件,此小软件练习的目的主要是为了体会编程思想,深度理解高内聚、低耦合,掌握编程思维逻辑的大招,告别垃圾代码,重点体会编程之美,练习时长30分钟;
开发一个项目之前,切记不要打开程序就写代码,首先要做的就是分析项目,从项目的架构开始思考,软件要实现什么功能(思考UI界面布局);数据从哪里获取?(数据库、文本文件、通讯接口...);重点思考项目对象、功能有哪些?(对象的属性、方法,之间的关系...),以此项目为例,思维导图如下:
No1. 软件实现的功能有哪些?(UI如何设计)

答: 用一个主界面实现,有标题栏(项目名称及关闭按钮)、菜单栏(上一题、下一题、提交按钮)、内容显示题目,选项以勾选的方式答题,最后提交得出总分;
No2.数据在哪里获取?

答: 文本文件(是否可靠,避免用户更改源文件,进一步优化—用到的技能:文本文件操作)
No3.对象有哪些,它们之间的关系是什么?

答: 软件运行强相关的对象有试卷、试题、答案(正确答案、错误答案);一张试卷中若干试题(一对多),试题在试卷中以集合的方式存在;试题的答案唯一(一对一),答案在试题中以对象属性的形式存在;
No4.如何设计类(列出属性、方法)?

答: 窗体加载试卷对象(试题加载(答案));从最底层答案类开始设计:
【答案类】
属性:所选答案、正确答案;
  1. /// <summary>
  2. /// 答案类(属性<成员变量>:所选答案、正确答案)
  3. /// </summary>
  4. [Serializable]  //实体类需序列化保存
  5. public class Answer
  6. {
  7.     public string SelectAnswer { get; set; } = string.Empty;
  8.     public string RightAnswer { get; set; } = string.Empty;
  9. }
复制代码
【试题类】
属性:题干、选项、答案(对象属性);
  1. /// <summary>
  2. /// 试题类(属性:题干、答案<对象属性-构造函数初始化>)
  3. /// </summary>
  4. [Serializable]
  5. public class Question
  6. {
  7.     public Question()  //构造函数初始化
  8.     {
  9.         QueAnswer = new Answer();
  10.     }
  11.     public string Title { get; set; } = string.Empty;
  12.     public string DescriptionA { get; set; } = string.Empty;
  13.     public string DescriptionB { get; set; } = string.Empty;
  14.     public string DescriptionC { get; set; } = string.Empty;
  15.     public string DescriptionD { get; set; } = string.Empty;
  16.     public Answer QueAnswer { get; set; }  //答案为对象属性
  17. }
复制代码
【试卷类】
属性:试题集合List;
方法:计算总分、读取文本(抽取试题);
  1. using System.IO;
  2. using System.Runtime.Serialization.Formatters.Binary;
  3. namespace WindowsFormsApp_试卷抽题.Models
  4. {
  5.     /// <summary>
  6.     /// 试卷类(属性:试题集合、  方法:抽题、分数)
  7.     /// </summary>
  8.     public class Paper
  9.     {
  10.         //构造函数初始化(对象属性)
  11.         public Paper()
  12.         {
  13.             questions = new List<Question>();
  14.         }
  15.         //字段:试题对象集合
  16.         private List<Question> questions;
  17.         //属性:只读
  18.         public List<Question> Questions { get { return this.questions; } }
  19.         //方法:分数【遍历试题选择的答案与正确答案相等即可得分】
  20.         public int Grade()
  21.         {
  22.             int score = 0;
  23.             foreach (Question item in questions)
  24.             {
  25.                 if (item.QueAnswer.SelectAnswer == string.Empty) continue;
  26.                 if (item.QueAnswer.SelectAnswer.Equals(item.QueAnswer.RightAnswer)) score += 5;
  27.             }
  28.             return score;
  29.         }
  30.         //方法:抽题:【初始化(1.读文件 2.保存为序列化文件 3.打开序列化文件)】
  31.         //读文本文件
  32.         public void OpenPaper1()
  33.         {
  34.             FileStream fs = new FileStream("questions.txt", FileMode.Open);
  35.             StreamReader sr = new StreamReader(fs, Encoding.Default); //注意默认编码方法
  36.             string txtPaper = sr.ReadToEnd();  //读取全部内容到txtPaper
  37.             string[] txtQuestions = txtPaper.Trim().Split('&');  //分割内容保存到试题数组;注意去空格
  38.             string[] txtQuestion = null; //保存一道题到txtQuestion
  39.             foreach (string item in txtQuestions)
  40.             {
  41.                 txtQuestion = item.Trim().Split('\r');
  42.                 this.questions.Add(new Question
  43.                 {
  44.                     Title = txtQuestion[0].Trim(),
  45.                     DescriptionA = txtQuestion[1].Trim(),
  46.                     DescriptionB = txtQuestion[2].Trim(),
  47.                     DescriptionC = txtQuestion[3].Trim(),
  48.                     DescriptionD = txtQuestion[4].Trim(),
  49.                     QueAnswer = new Answer { RightAnswer = txtQuestion[5].Trim() }
  50.                 });
  51.             }
  52.             sr.Close();
  53.             fs.Close();
  54.         }
  55.         //保存为序列化文件
  56.         public void SavePaper()
  57.         {
  58.             FileStream fs = new FileStream("Paper.obj", FileMode.Create); //创建文件
  59.             BinaryFormatter bf = new BinaryFormatter();  //序列化器
  60.             bf.Serialize(fs, this.questions);  //序列化对象
  61.             fs.Close();
  62.         }
  63.         //打开序列化文件【保存文件后用此方法将独到的数据传递到试题集合中即可】
  64.         public void OpenPaper2()
  65.         {
  66.             FileStream fs = new FileStream("Paper.obj", FileMode.Open); //打开文件
  67.             BinaryFormatter bf = new BinaryFormatter(); //序列化器
  68.             this.questions = (List<Question>)bf.Deserialize(fs);  //反序列化到对象
  69.             fs.Close();
  70.         }
  71.     }
  72. }
复制代码
【边界类】
属性:试卷对象;
方法:显示题目、保存答案、重置答案;
  1. /// <summary>
  2. /// 边界类:试卷对象、题序  方法:显示题目、保存答案、重置答案
  3. /// </summary>
  4. public partial class FrmMain : Form
  5. {
  6.     //窗口初始化
  7.     public FrmMain()
  8.     {
  9.         InitializeComponent();
  10.         this.palCover.Visible = true;
  11.         this.lblView.Text = "试卷密封中,等待抽题......";
  12.     }
  13.     //试卷对象、题序号
  14.     private Paper Paper = new Paper();
  15.     private int QuestionIndex = 0;
  16.     //开始抽题
  17.     private void btnStart_Click(object sender, EventArgs e)
  18.     {
  19.         this.palCover.Visible = false;
  20.         //显示第一题
  21.         this.Paper.OpenPaper1();  //打开txt文件
  22.         //this.Paper.SavePaper();  //保存文序列化文件
  23.         //this.Paper.OpenPaper2();   //反序列化打开试卷
  24.         ShowPaper();
  25.     }
  26.     //提交试卷
  27.     private void btnSubmit_Click(object sender, EventArgs e)
  28.     {
  29.         this.palCover.Visible = true;
  30.         //保存答案并判断
  31.         SaveAnswer();
  32.         int score = this.Paper.Grade();
  33.         //显示成绩
  34.         this.lblView.Text = $"您的得分是: {score}  分";
  35.     }
  36.     //上一题
  37.     private void btnUp_Click(object sender, EventArgs e)
  38.     {
  39.         if (QuestionIndex == 0) return;
  40.         else
  41.         {
  42.             SaveAnswer();
  43.             QuestionIndex--;
  44.             ResetAnswer();
  45.             ShowPaper();
  46.         }
  47.     }
  48.     //下一题
  49.     private void btnDown_Click(object sender, EventArgs e)
  50.     {
  51.         if (QuestionIndex == Paper.Questions.Count - 1) return;
  52.         else
  53.         {
  54.             SaveAnswer();
  55.             QuestionIndex++;
  56.             ResetAnswer();
  57.             ShowPaper();
  58.         }
  59.     }
  60.     //显示试题
  61.     public void ShowPaper()
  62.     {
  63.         this.lblTiltle.Text = this.Paper.Questions[this.QuestionIndex].Title;
  64.         this.lblA.Text = this.Paper.Questions[this.QuestionIndex].DescriptionA;
  65.         this.lblB.Text = this.Paper.Questions[this.QuestionIndex].DescriptionB;
  66.         this.lblC.Text = this.Paper.Questions[this.QuestionIndex].DescriptionC;
  67.         this.lblD.Text = this.Paper.Questions[this.QuestionIndex].DescriptionD;
  68.     }
  69.     //保存答案
  70.     public void SaveAnswer()
  71.     {
  72.         string selecetAnswer = string.Empty;
  73.         if (this.ckbA.Checked) selecetAnswer += "A";
  74.         if (this.ckbB.Checked) selecetAnswer += "B";
  75.         if (this.ckbC.Checked) selecetAnswer += "C";
  76.         if (this.ckbD.Checked) selecetAnswer += "D";
  77.         this.Paper.Questions[QuestionIndex].QueAnswer.SelectAnswer = selecetAnswer;
  78.         
  79.     }
  80.     //重置答案
  81.     public void ResetAnswer()
  82.     {
  83.         this.ckbA.Checked = this.Paper.Questions[this.QuestionIndex].QueAnswer.SelectAnswer.Contains("A");
  84.         this.ckbB.Checked = this.Paper.Questions[this.QuestionIndex].QueAnswer.SelectAnswer.Contains("B");
  85.         this.ckbC.Checked = this.Paper.Questions[this.QuestionIndex].QueAnswer.SelectAnswer.Contains("C");
  86.         this.ckbD.Checked = this.Paper.Questions[this.QuestionIndex].QueAnswer.SelectAnswer.Contains("D");
  87.     }
  88.     //退出
  89.     private void btnClose_Click(object sender, EventArgs e)
  90.     {
  91.         this.Close();
  92.     }
  93. }
复制代码
软件效果


思维导图如下所示(重点体会思路,思路清晰代码就成了):



来源:https://www.cnblogs.com/guoenshuo/p/18355969
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
来自手机

举报 回复 使用道具