最近我用c#为我们学校一个老师写了一个点名用的小软件,也算是复习一下c#吧。(下载链接在最后)
这是整体界面:
使用前准备:
1.打开名为“课程”的文件夹,在该文件夹下创建一个子文件夹
(文件夹名即是课程名)在此先命名为子文件夹1
2.在子文件夹1的目录下,创建两个txt文本文件
3.往文本文件中按格式填充内容,格式如下:
编号|学号|名字(例:00|1336210008|张三)学号的长度不唯一
4.两个文本文件内容一致,其中一个文本命名为"表现情况",
另一个命名为"抽奖名单"。 (为了方便两个txt文件的生成,特意写了一个程序实现了Excel转换成该格式的txt文件,在后面会展示代码)
5.在文件夹1目录下,再创建一个名为imgs的用于存放图片的
子文件夹,用于存放.jpg图片(图片名必须与上面的编号一致)
6.至此一个班级的文档创建成功。
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
使用方法:
双击“点名器.exe”,在菜单目录下可以选择模式(默认为剔除模式)
剔除模式:每点完一个学生,则将他剔除,下次不会出现,知道所有学生都轮
到过一次。新的一轮点名开始
不剔除模式:点过的学生不会被剔除,下次也有可能被抽到
学长寄语的文本由课程文件夹下的名为学长寄语的txt文本内容
图片下有一个下拉框,选择需要点名的班级,选择成功之后会弹出“名单添加成功”
的对话框。
点击开始按钮,点名开始,按钮编程停止,再次点击,点名结束,学生信息显示。
学生答题结束后老师进行点评,在单选框中选择点击提交成绩按钮,成绩提交。
点名结束。
以下是点名器代码的展示:
1 首先是全局变量的声明
2 //模式转换标志位 true为剔除学生版本 false为不剔除版本
3 bool mold=true;
4 Student selectStudent;
5 int removeAndScore;
6 //是否打过分数的标志符
7 bool IsScored = false;
8 string strAutoId;
9 string path;
10 //用于存储课程名字的集合
11 List<string> classListName = new List<string>();
12 //用于存储学生信息的集合
13 List<Student> studentList = new List<Student>();
1 窗体加载时
2 private void Form1_Load(object sender, EventArgs e)
3 {
4 //在下来菜单中加载课程信息
5 string[] classPathes = Directory.GetDirectories("课程");
6 foreach (var classPath in classPathes)
7 {
8 string className = classPath.Substring(classPath.LastIndexOf('\\')+1);
9 classListName.Add(className);
10 cboClassSelect.Items.Add(className);
11 }
12 string Mytext = File.ReadAllText(@"课程\学长寄语.txt",Encoding.Default);
13 lblJiYu.Text = Mytext;
14 }
1 加载学生信息
2 /// <summary>
3 /// 选择课程添加学生名单
4 /// </summary>
5 /// <param name="sender"></param>
6 /// <param name="e"></param>
7 private void cboClassSelect_SelectedIndexChanged(object sender, EventArgs e)
8 {
9 try
10 {
11 if (cboClassSelect.SelectedIndex <= 0)
12 {
13 //未正确选择课程
14 MessageBox.Show("请先选择课程!!!");
15 return;
16 }
17 //选择了课程,加载该课程的所有学生的信息
18 studentList.Clear();
19 int studentAutoId = 0;
20 int index = Convert.ToInt32(cboClassSelect.SelectedIndex);
21 path = "课程\\" + classListName[index - 1];
22 if (mold)
23 {
24 //剔除学生模式下的加载学生
25 using (StreamReader sReader = new StreamReader(path + "\\抽奖名单.txt", Encoding.Default))
26 {
27 string line = null;
28 while ((line = sReader.ReadLine()) != null)
29 {
30 string[] studentMsg = line.Split('|');
31 if (studentMsg.Length == 3)
32 {
33 Student model = new Student();
34 //21|1336210021|赵本山
35 model.StudentImgPath = path + "\\imgs\\" + studentMsg[0] + ".jpg";
36 model.StudentId = int.Parse(studentMsg[1]);
37 model.StudentName = studentMsg[2];
38 model.StudentAutoId = studentAutoId;
39 studentList.Add(model);
40 studentAutoId++;
41 }
42 }
43 }
44 if (studentList.Count == 0)
45 {
46 //所有学生都被点完
47 ResetStudentMsg();
48 using (StreamReader sReader = new StreamReader(path + "\\抽奖名单.txt", Encoding.Default))
49 {
50 string line = null;
51 while ((line = sReader.ReadLine()) != null)
52 {
53 string[] studentMsg = line.Split('|');
54 if (studentMsg.Length == 3)
55 {
56 Student model = new Student();
57 //21|1336210021|赵本山
58 model.StudentImgPath = path + "\\imgs\\" + studentMsg[0] + ".jpg";
59 model.StudentId = int.Parse(studentMsg[1]);
60 model.StudentName = studentMsg[2];
61 model.StudentAutoId = studentAutoId;
62 studentList.Add(model);
63
64 }
65 }
66 }
67 }
68 }
69 else
70 {
71 //不剔除学生模式下的加载学生
72 using (StreamReader sReader = new StreamReader(path + "\\抽奖名单.txt", Encoding.Default))
73 {
74 string line = null;
75 while ((line = sReader.ReadLine()) != null)
76 {
77 string[] studentMsg = line.Split('|');
78 Student model = new Student();
79 //21|1336210021|赵本山
80 model.StudentImgPath = path + "\\imgs\\" + studentMsg[0] + ".jpg";
81 model.StudentId = int.Parse(studentMsg[1]);
82 model.StudentName = studentMsg[2];
83 model.StudentAutoId = studentAutoId;
84 studentList.Add(model);
85
86 }
87 }
88 }
89 MessageBox.Show("名单添加成功!!!");
90 lblShowMsg.Text = "台州学院" + classListName[cboClassSelect.SelectedIndex-1] + "上课使用";
91 if (mold)
92 {
93 lblMold.Text = "您选择了剔除学生版本";
94 }
95 else
96 {
97 lblMold.Text = "您选择了不剔除学生版本";
98 }
99 }
100 catch
101 { }
102 }
加载学生信息的代码严重违背了DRY,代码的冗余太明显了,不过当时也没有认真的把它优化,只想着赶快完成任务,所以有待优化。
1 按钮的点击事件(开始点名)
2 /// <summary>
3 /// 按钮点击事件,触发定时器工作
4 /// </summary>
5 /// <param name="sender"></param>
6 /// <param name="e"></param>
7 private void btnStartGame_Click(object sender, EventArgs e)
8 {
9 if (cboClassSelect.SelectedIndex <= 0)
10 {
11 MessageBox.Show("请先选择班级");
12 return;
13 }
14 if (studentList.Count == 0)
15 {
16 MessageBox.Show("没有学生了");
17 return;
18 }
19
20 if (btnStartGame.Text == "开始")
21 {
22 if (selectStudent != null && IsScored == false)
23 {
24 MessageBox.Show("答得再差也得给个分吧!");
25 return;
26 }
27 btnStartGame.Text = "结束";
28 timer1.Enabled = true;
29 IsScored = false;
30 this.radioButton1.Enabled = false;
31 this.radioButton2.Enabled = false;
32 this.radioButton3.Enabled = false;
33 this.radioButton4.Enabled = false;
34 }
35 else if (btnStartGame.Text == "结束")
36 {
37
38 btnStartGame.Text = "开始";
39 timer1.Enabled = false;
40 this.radioButton1.Enabled = true;
41 this.radioButton2.Enabled = true;
42 this.radioButton3.Enabled = true;
43 this.radioButton4.Enabled = true;
44 try
45 {
46 if (mold)
47 {
48 ChangeStudentMsg();
49 //if (studentList.Count >= 1)
50 //{
51 studentList.RemoveAt(removeAndScore);
52 //}
53 }
54 else
55 {
56 selectStudent = studentList[removeAndScore];
57 }
58 }
59 catch
60 { }
61 }
62 }
1 定时器的触发事件,设定了每20ms触发一次,每次触发会随机在学生列表中产生一个幸运者
2 /// <summary>
3 /// 开始点名
4 /// </summary>
5 /// <param name="sender"></param>
6 /// <param name="e"></param>
7 private void timer1_Tick(object sender, EventArgs e)
8 {
9 try
10 {
11 Random r = new Random();
12 strAutoId = r.Next(0, studentList.Count).ToString();
13 removeAndScore = int.Parse(strAutoId);
14 //strAutoId = strAutoId.Length == 1 ? "0" + strAutoId : strAutoId;
15 pBImg.Image = Image.FromFile(studentList[removeAndScore].StudentImgPath);
16 lblStudentId.Text = studentList[removeAndScore].StudentId.ToString();
17 lblStudentName.Text = studentList[removeAndScore].StudentName;
18 }
19 catch
20 {
21
22 }
23 }
1 答题结束后,老师打分
2 /// <summary>
3 /// 提交表现情况
4 /// </summary>
5 /// <param name="sender"></param>
6 /// <param name="e"></param>
7 private void btnScore_Click(object sender, EventArgs e)
8 {
9 if (IsScored)
10 {
11 MessageBox.Show("已经打过分了");
12 return;
13 }
14 if (btnStartGame.Text == "结束")
15 {
16
17 return;
18 }
19 string result=null;
20 bool radioBtn1 = this.radioButton1.Checked;
21 bool radioBtn2 = this.radioButton2.Checked;
22 bool radioBtn3 = this.radioButton3.Checked;
23 bool radioBtn4 = this.radioButton4.Checked;
24 if (!(radioBtn1 || radioBtn2 || radioBtn3 || radioBtn4))
25 {
26 MessageBox.Show("请先打分");
27 return;
28 }
29 if (radioBtn1)
30 {
31 result = "完美";
32 }
33 if (radioBtn2)
34 {
35 result = "还行";
36 }
37 if (radioBtn3)
38 {
39 result = "仍需努力";
40 }
41 if (radioBtn4)
42 {
43 result = "要挨揍了";
44 }
45 //答完题的学生被移除
46 List<string> listText = new List<string>();
47 //Student selectStudent = studentList[removeAndScore];
48 using (StreamReader sReader = new StreamReader(path + "\\表现情况.txt", Encoding.Default))
49 {
50 string line = null;
51 while ((line = sReader.ReadLine()) != null)
52 {
53 //把所有行读入集合
54 listText.Add(line);
55 }
56
57 }
58 for (int i = 0; i < listText.Count; i++)
59 {
60 if (listText[i].Split('|')[2] == selectStudent.StudentName)
61 {
62 listText[i] = listText[i] +"|"+ result;
63 }
64 }
65 using (StreamWriter sWriter = new StreamWriter(path + "\\表现情况.txt", false, Encoding.Default))
66 {
67 for (int i = 0; i < listText.Count; i++)
68 {
69 sWriter.WriteLine(listText[i]);
70 }
71 }
72 MessageBox.Show("打分成功");
73 IsScored = true;
74 this.radioButton1.Checked = false;
75 this.radioButton2.Checked = false;
76 this.radioButton3.Checked = false;
77 this.radioButton4.Checked = false;
78 }
1 修改学生信息,在剔除学生的模式下,没有一个学生被点中,抽奖名单.txt文件中对应的学生后面会加上selected的标记,一旦被标记,下次不会加载到学生列表,从而实现了逻辑删除。以下代码就是添加selected
2 /// <summary>
3 /// 修改学生信息
4 /// </summary>
5 private void ChangeStudentMsg()
6 {
7 //答完题的学生被移除
8 List<string> listText = new List<string>();
9 selectStudent = studentList[removeAndScore];
10 using (StreamReader sReader = new StreamReader(path + "\\抽奖名单.txt", Encoding.Default))
11 {
12 string line = null;
13 while ((line = sReader.ReadLine()) != null)
14 {
15 //把所有行读入集合
16 listText.Add(line);
17 }
18
19 }
20 for (int i = 0; i < listText.Count; i++)
21 {
22 if (listText[i].Split('|')[2] == selectStudent.StudentName)
23 {
24 listText[i] = listText[i] + "|selected";
25 }
26 }
27 using (StreamWriter sWriter = new StreamWriter(path + "\\抽奖名单.txt", false, Encoding.Default))
28 {
29 for (int i = 0; i < listText.Count; i++)
30 {
31 sWriter.WriteLine(listText[i]);
32 }
33 }
34 }
1 重置学生信息,也是在剔除模式下,当所有学生都被点过之后,需要把selected全部去掉,下一次加载就是全新的一次,所有学生都会加载
2 /// <summary>
3 /// 重置学生信息
4 /// </summary>
5 private void ResetStudentMsg()
6 {
7 List<string> listText = new List<string>();
8 using (StreamReader sReader = new StreamReader(path + "\\抽奖名单.txt", Encoding.Default))
9 {
10 string line = null;
11 while ((line = sReader.ReadLine()) != null)
12 {
13 //把所有行读入集合
14 listText.Add(line);
15 }
16
17 }
18 for (int i = 0; i < listText.Count; i++)
19 {
20 string[] studentMsg = listText[i].Split('|');
21 listText[i] = studentMsg[0] +"|"+ studentMsg[1] +"|"+ studentMsg[2];
22 }
23 using (StreamWriter sWriter = new StreamWriter(path + "\\抽奖名单.txt", false, Encoding.Default))
24 {
25 for (int i = 0; i < listText.Count; i++)
26 {
27 sWriter.WriteLine(listText[i]);
28 }
29 }
30 }
1 以下就是模式的切换,还有退出键,相当简单的一段代码
2 private void 不剔除版ToolStripMenuItem_Click(object sender, EventArgs e)
3 {
4 if (cboClassSelect.SelectedIndex <= 0)
5 {
6 MessageBox.Show("请先选择班级");
7 return;
8 }
9 mold = false;
10 lblMold.Text = "您选择了不剔除学生版本";
11 ResetStudentMsg();
12 }
13
14 private void 提出版ToolStripMenuItem_Click(object sender, EventArgs e)
15 {
16 mold = true;
17 lblMold.Text = "您选择了剔除学生版本";
18 }
19
20 private void 退出ToolStripMenuItem_Click(object sender, EventArgs e)
21 {
22 this.Close();
23 }
至此,点名器全部代码写完
后面是Excel2txt的代码
在写代码之前,必须要引用两个程序集
可以去网上下载(Ionic.Zip.dll,NPOI.dll)也可以复制链接下载http://pan.baidu.com/s/1ge8gVV9
//选取xls文件的路径
string path = string.Empty;
1 /// <summary>
2 /// 选取文件路径
3 /// </summary>
4 /// <param name="sender"></param>
5 /// <param name="e"></param>
6 private void btnPath_Click(object sender, EventArgs e)
7 {
8 OpenFileDialog ofd = new OpenFileDialog();
9 ofd.Title = "选择一个Excel文件";
10 ofd.InitialDirectory = @"C:\Users\Administrator\Desktop";
11 ofd.Filter = "Excel|*.xls|所有文件|*.*";
12 ofd.ShowDialog();
13 path = ofd.FileName;
14 textBox1.Text = path;
15 }
1 /// <summary>
2 /// 转换成txt
3 /// </summary>
4 /// <param name="sender"></param>
5 /// <param name="e"></param>
6 private void btnChange_Click(object sender, EventArgs e)
7 {
8 if (path == string.Empty)
9 {
10 MessageBox.Show("请选择一个Excle文件进行转换");
11 return;
12 }
13 StringBuilder sb = new StringBuilder();
14 //创建一个文件流,指向磁盘的某个 Excel文件
15 using (FileStream fsRead = File.OpenRead("ReadExcel.xls"))
16 {
17 //创建一个workbook对象(工作簿对象)
18 //根据某个文件流创建工作簿对象
19 IWorkbook wk = new HSSFWorkbook(fsRead);
20
21 //读取工作簿中表的个数
22 for (int i = 0; i < 1; i++)
23 {
24 //获得当前的表
25 ISheet sheet = wk.GetSheetAt(i);
26 int rowNum = 0;
27 //获得当前表的行的个数
28 for (int j = 1; j <= sheet.LastRowNum; j++)
29 {
30 IRow row = sheet.GetRow(j);
31 string id = rowNum < 10 ? "0" + rowNum.ToString() : rowNum.ToString();
32 rowNum++;
33 sb.Append(id + "|");
34 //获取当前行的每个单元格
35 for (int k = 0; k < 2; k++)
36 {
37 ICell cell = row.GetCell(k);
38
39
40 sb.Append(cell.ToString()+"|");
41 //Console.Write(cell.ToString()+"|");
42 }
43 sb.Remove(sb.Length - 1, 1);
44 sb.Append("\r\n");
45 }
46 }
47 }
48 using (StreamWriter sWriter=new StreamWriter ("test.txt"))
49 {
50 sWriter.WriteLine(sb.ToString());
51 }
52 MessageBox.Show("ok");
53 }
当然了,点名器也好,Excel2txt也好,都是入门级的东西,大神勿喷,作为一个初涉.net的菜鸟,就让我发表一下吧。