个人第三次作业:结对编程
一、基本信息
1.git地址:https://github.com/caiyulan/PairProgramming.git
2.结对伙伴作业地址:https://www.cnblogs.com/zhengxue666/p/11614491.html
二、结对准备
1.PSP表格
PSP2.1 | Personal software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
painning | 计划 | 30 | 20 |
· Estimate | · 估计这个任务需要多少时间 | 10 | 10 |
Development | 开发 | 400 | 320 |
· Analysis | · 需求分析 (包括学习新技术) | 30 | 20 |
· Design Spec | · 生成设计文档 | 50 | 30 |
· Design Review | · 设计复审 (和同事审核设计文档) | 20 | 20 |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 20 | 20 |
· Design | · 具体设计 | 60 | 40 |
· Coding | · 具体编码 | 120 | 100 |
· Code Review | · 代码复审 | 40 | 30 |
· Test | · 测试(自我测试,修改代码,提交修改) | 60 | 60 |
Reporting | 报告 | 70 | 60 |
· Test Report | · 测试报告 | 30 | 30 |
· Size Measurement | · 计算工作量 | 20 | 20 |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 20 | 10 |
合计 | 500 | 410 |
2.结对过程
拿到新的作业后首先和郑雪同学组了队,老师在课堂上讲了大概的做法,下来就讨论了一下在哪些方面进行创新。进行了一些基本分工以后就开始做啦~结对编程的过程都是我们一起在我的电脑上完成的。
3.代码规范
命名使用驼峰命名法,缩进就按系统自动缩进方式,对关键代码进行注释。
三、编码过程
1.代码设计
(1)界面设计,主要两个功能。一个是将Excel的数据导入到DataGirdView中并显示,另外一个就是随机点名,对应设置了控件。
(2)加载皮肤,使用了skinEnige控件,运行效果如下:
(3)打开文件,用OpenFileDialog获取文件的路径,将路径放置到textbox中,通过combox来选取表单,代码借鉴于《C#开发——winform中将Excel数据导入DataGridView》,但有部分还不是很懂,using...那块不是很明白,主要代码如下:
private void btnopenfile_Click(object sender, EventArgs e)
{
try
{
//获取Excel文件路径和名称
OpenFileDialog odXls = new OpenFileDialog();
//指定相应的打开文档的目录 AppDomain.CurrentDomain.BaseDirectory定位到Debug目录,再根据实际情况进行目录调整
string folderPath = AppDomain.CurrentDomain.BaseDirectory + @"databackup\";
odXls.InitialDirectory = folderPath;
// 设置文件格式
odXls.Filter = "Excel files office2003(*.xls)|*.xls|Excel office2010(*.xlsx)|*.xlsx|All files (*.*)|*.*";
//openFileDialog1.Filter = "图片文件(*.jpg)|*.jpg|(*.JPEG)|*.jpeg|(*.PNG)|*.png";
odXls.FilterIndex = 2;
odXls.RestoreDirectory = true;
if (odXls.ShowDialog() == DialogResult.OK)
{
this.txtFilePath.Text = odXls.FileName;
this.txtFilePath.ReadOnly = true;
string sConnString = string.Format("Provider=Microsoft.ACE.OLEDB.12.0;" + "Data Source={0};" + "Extended Properties='Excel 8.0;HDR=NO;IMEX=1';", odXls.FileName);
if ((System.IO.Path.GetExtension(txtFilePath.Text.Trim())).ToLower() == ".xls")
{
sConnString = "Provider=Microsoft.Jet.OLEDB.4.0;" + "data source=" + odXls.FileName + ";Extended Properties=Excel 5.0;Persist Security Info=False";
//sConnString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + txtFilePath.Text.Trim() + ";Extended Properties=\"Excel 8.0;HDR=" + strHead + ";IMEX=1\"";
}
using (OleDbConnection oleDbConn = new OleDbConnection(sConnString))
{
oleDbConn.Open();
DataTable dt = oleDbConn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" });
//判断是否cmb中已有数据,有则清空
if (cmbtablename.Items.Count > 0)
{
cmbtablename.DataSource = null;
cmbtablename.Items.Clear();
}
//遍历dt的rows得到所有的TABLE_NAME,并Add到cmb中
foreach (DataRow dr in dt.Rows)
{
cmbtablename.Items.Add((String)dr["TABLE_NAME"]);
}
if (cmbtablename.Items.Count > 0)
{
cmbtablename.SelectedIndex = 0;
}
//加载Excel文件数据按钮
this.btnshow.Enabled = true;
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
(3)加载数据,#region为折叠代码所用,主要设置连接字符串,与连接数据库类似,通过DataAdapter、DataTable及其相应属性加载数据。
private void btnshow_Click(object sender, EventArgs e)
{
#region 读取相应的表名的Excel文件中数据到当前DataGridview中显示
OleDbConnection ole = null;
OleDbDataAdapter da = null;
DataTable dt = null;
string strConn = string.Format("Provider=Microsoft.ACE.OLEDB.12.0;" + "Data Source={0};" + "Extended Properties='Excel 8.0;HDR=NO;IMEX=1';", txtFilePath.Text.Trim());
if ((System.IO.Path.GetExtension(txtFilePath.Text.Trim())).ToLower() == ".xls")
{
strConn = "Provider=Microsoft.Jet.OLEDB.4.0;" + "data source=" + txtFilePath.Text.Trim() + ";Extended Properties=Excel 5.0;Persist Security Info=False";
//sConnString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + txtFilePath.Text.Trim() + ";Extended Properties=\"Excel 8.0;HDR=" + strHead + ";IMEX=1\"";
}
string sTableName = cmbtablename.Text.Trim();
string strExcel = "select * from [" + sTableName + "]";
try
{
ole = new OleDbConnection(strConn);
ole.Open();
da = new OleDbDataAdapter(strExcel, ole);
dt = new DataTable();
da.Fill(dt);
this.dgvdata.DataSource = dt;
//因为生成Excel的时候第一行是标题,所以要做如下操作:
//1.修改DataGridView列头的名字,
//2.数据列表中删除第一行
for (int i = 0; i < dt.Columns.Count; i++)
{
//dgvdata.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
//dgvdata.Columns[i].Name = dt.Columns[i].ColumnName;
dgvdata.Columns[i].HeaderCell.Value = dt.Rows[0][i].ToString();//c# winform 用代码修改DataGridView列头的名字,设置列名,修改列名
}
//DataGridView删除行
dgvdata.Rows.Remove(dgvdata.Rows[0]);/
ole.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
if (ole != null)
ole.Close();
}
#endregion
setControlVisible();
}
(4)随机点名,生成随机数放到标签里,用Timer的start和stop控制进行和停止。这里遇到的一个问题是lblName.Text是object类型,而表单元格内是字符串类型不能转换,上网查阅之后进行了装箱拆箱解决了问题。
private void timerCallName_Tick(object sender, EventArgs e)
{
Object obj= lblName.Text;
String str = (String)obj;
Random ra = new Random();
int i = ra.Next(dgvdata.Rows.Count);
lblName.Text = (String)dgvdata.Rows[i].Cells[1].Value;
}
2.代码复审
在实现成功运行后,进行了对代码的复审,对一些冗余的代码进行了删除,经过共同协商决定加载数据后不设置按钮的隐藏,这样就可以加载不同的班级,过程当中没有遇到什么问题。但获取同学名字这里,如果名字的列位置发生了变化就会发生错误,就可能得到的不是名字列,还没想到什么办法可以优化。
3.单元测试
对界面和btnshow点击事件能否成功进行进行了测试,覆盖率如下:
4.附加功能
1.皮肤
2.从Excel导入数据
四、心得体会
经过此次结对编程也学到了很多东西,两个人一起解决问题的效率会比一个人的时候更高,一些自己不易发现的错误也会及时被结对同伴发现,减少了很多后面改正的时间。有实现1+1>2