最近我用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的菜鸟,就让我发表一下吧。
点名器和Excel2txt链接:http://pan.baidu.com/s/1kUAGC0f 密码:x5lj
以上,感谢您的阅读