目录
1.在原来【例9.3】项目的主窗体中增加一个“个人明细”命令按钮。
1.修改程序,以编程方式实现DataSet和DataAdapter等数据控件的创建。
2.修改程序,实现当双击DataGridView控件的每一行记录时,弹出该学生个人明细信息窗口功能。
3.使用上面介绍的方法,在明细窗口中增加显示数据库中某学生的其他一些个人专项信息,如学生所在专业、总学分、备注信息等。
实验目的:
- 熟悉数据库的基本功能与SQL语言的使用,掌握数据库应用的基本方法。
- 掌握将查询结果与数据集绑定,并在相应控件上同步显示查询结果的方法。
实验内容:
【实验9-1】
为【例9.3】添加一项新的功能,单击“个人明细”按钮,弹出一个简单的个人信息浏览界面,它支持向前和向后翻页显示每一个学生的信息。
A.跟着学习
- 设计页面
按照【例9.3】说明完成功能。
【例9.3】利用数据集机制,使用DataAdapter对象填充DataSet的方法,离线访问XSCJDB数据库。
- 创建数据库。
默认已经存在的数据库。
创建XSCJDB数据库。
如图所示,创建成功。
右键单击数据库实例节点,选择“新建查询”,在查询语句编辑窗口中输入以下命令语句:
alter database XSCJDB collate Chinese_PRC_CI_AS;
然后执行该语句。
- 创建表。
右键单击“表”节点,选择“添加新表”选项。如下图。
在“dbo.Table[设计]”窗口中编辑设置表各列的名称,数据类型,是否允许空值及默认值等属性。如下图。其中,XH表示“学号”,XM表示“姓名”,XB表示“性别”,CSRQ表示“出生日期”,ZY表示“专业”,ZXF表示“总学分”,BZ表示“备注”。编辑完成后,将窗口下部的T-SQL子窗口中表名修改为XSB。
编辑完成后,单击设计窗口左上方的更新按钮,会弹出“预览数据库更新”对话框,点击“更新数据库”按钮。提交对数据库的更改,系统开始执行创建表的操作。
稍等一会儿,底部“数据工具操作”底部显示已成功更新。
此时,点击展开XSCJDB节点,如下图所示,可在“表”子节点下多了dbo.XSB项,表示学生表XSB创建成功。进一步展开其下的“列”节点,可以看到表的各列字段名及数据类型等信息。
至此,学生表XSB创建完成。用相同的方法创建课程表KCB和成绩表CJB。
课程表KCB:
成绩表CJB:注意:设置主码为XH和KCH
至此,创建学生表XSB,课程表KCB,成绩表CJB操作已完成。
- 录入数据
右键单击dbo.XSB,选择“查看数据”选项,进入编辑即可。
为XSB和CJB都录入数据。
至此,相关数据库操作完成。
- 新建WinForm项目。在Form1的设计视图中将此窗体调整到适当的大小并将Text属性设为“离线访问数据源”。从工具箱中拖曳1个GroupBox、2个Button、4个TextBox、2个RadioButton、1个DateTimePicker、6个Label控件和1个DataGridView控件到此窗体中,并设计界面。如下图。
【注】在接下来的实验中,在添加了using System.Data.SqlClient后,仍然在使用SqlConnection类的时候一直报错“未能在命名空间System.Data.SqlClient中找到类型名SqlConnection,在搜索资料后,解决办法是用NuGet包管理器手动添加。选择“工具栏”→“NuGet包管理器”→“程序包管理器控制台”输入Install-Package System.Data.sqlClient.如下图:
下载添加完成后右边项目的依赖项里会多出“System.Data.SqlClient”引用即可。
- 程序的完整代码:
using System.Data;
using System.Data.SqlClient;
namespace WinForm9_1
{
public partial class Form1 : Form
{
string strcon = @"Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=XSCJDB;Integrated Security=True";
//Sqlconnection sqlcon = new Sqlconnection(strcon);
DataSet myst = new DataSet();
SqlDataAdapter myda;
public Form1()
{
InitializeComponent();
btnSearch_Click(null, null);
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void btnInsert_Click(object sender, EventArgs e)
{
SqlConnection sqlcon = new SqlConnection(strcon);
try
{
string stuID = txtStuID.Text.Trim();
string stuName = txtName.Text.Trim();
string stuXB;
if(RbtnMale.Checked)
{
stuXB = "男";
}
else
{
stuXB = "女";
}
string stuBirthday = dateTimePicker1.Value.ToShortDateString().Split("")[0];
string stuMajor = txtMajor.Text.Trim();
string stuCredit = txtCredit.Text.Trim();
SqlCommand command = new SqlCommand();
command.CommandText = "INSERT INTO XSB(XH,XM,XB,CSRQ,ZY,ZXF) VALUES('" + stuID + "','" + stuName + "','" + stuXB + "','" + stuBirthday + "','" + stuMajor + "','" + stuCredit + "')";
command.CommandType = CommandType.Text;
command.Connection = sqlcon;
sqlcon.Open();
myda = new SqlDataAdapter(command);
myda.Fill(myst, "XSB");
MessageBox.Show("插入成功!", "消息", MessageBoxButtons.OK);
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
sqlcon.Close();
}
}
private void btnSearch_Click(object sender, EventArgs e)
{
using(SqlConnection sqlcon=new SqlConnection(strcon))
{
//刷新操作
sqlcon.Open();
//创建SqlCommand对象
string sql = "SELECT*FROM XSB";
SqlCommand command = new SqlCommand(sql, sqlcon);
myda = new SqlDataAdapter(command);
//以数据集填充发载入信息
myst.Tables.Clear();
myda.Fill(myst, "XSB");
//将DataGridView控件中的数据源设为myst中的数据表XSB
dgvAllStu.DataSource = myst.Tables["XSB"];
}
}
}
}
- 运行截图:
输入要添加学生信息:
点击添加:
点击确定,然后点击刷新后,就可以在最后一行看到刚添加的同学信息。
至此,【例9.3】已完成。
1.在原来【例9.3】项目的主窗体中增加一个“个人明细”命令按钮。
右键单击项目,选择“添加”→“Windows窗体”,窗体名称Name属性设置为SelfDetail,设置新窗体的FormBorderStyle属性为FixedDialog,添加控件如下表T9.1。
表T9.1 新添加的控件
控件名 | 类型 | 注释 |
btnFirst | 按钮 | 到第一条记录 Text=”|<” |
btnPrew | 按钮 | 到上一条记录 Text=”<” |
btnNext | 按钮 | 到下一条记录 Text=”>” |
btnLast | 按钮 | 到最末条记录 Text=”>|” |
btnClose | 按钮 | 单击关闭对话 Text=”关闭” |
Label1 | 标签 | 学号标签 Text=”学号” |
lblStudentNo | 标签 | 学号文本 Text=””,Modifiers=public |
Label2 | 标签 | 生日标签 Text=”生日” |
tbBirthday | 文本框 | 生日文本 Text=””,Modifiers=public |
如下图:
2.查询学生信息并绑定数据集
为“个人明细”按钮编写事件代码如下:
private void btnGRMX_Click(object sender, EventArgs e)
{
using (SqlConnection sqlcon = new SqlConnection(strcon))
{
sqlcon.Open();
//下面开始个人明细查询,并将查询生成的表SelfInfo与窗口frmSelf的数据集mdataSet同步绑定
string sql = "Select XH as'学号',XM as'姓名',CSRQ as'生日'from XSB";
SqlDataAdapter myda = new SqlDataAdapter(sql, sqlcon);
DataSet myst = new DataSet();
myda.Fill(myst, "SelfInfo");
frmSelf = new SelfDetail();
frmSelf.mDataSet = myst;
frmSelf.BindingContext = this.BindingContext;
frmSelf.DataBindings.Add("Text", myst, "SelfInfo.姓名");
frmSelf.lblStudentNo.DataBindings.Add("Text", myst, "SelfInfo.学号");
frmSelf.tbBirthday.DataBindings.Add("Text", myst, "SelfInfo.生日");
frmSelf.Show();
}
}
此时,还未在SelfDetail窗体中增加数据集对象mDataSet
在原来的主窗体的类中定义新窗体:
SelfDetail frmSelf;
3.编写控制逻辑
为了在窗体frmSelf中显示每一个学生的明细情况,需要向该窗体中建立数据集以便与控件进行绑定,由于已经在主窗体中建立过数据集,因此明细窗体中只需引用该数据集即可,所有必须在窗体的类中增加一个数据集对象:
internal DataSet mDataSet;
此外,当数据集指针指向第一个或最后一个记录时,向前或向后按钮应该无效,这里可以为窗体类添加一个控制按钮状态的ButtonStateControl()方法:
private void ButtonStateControl()
{
btnFirst.Enabled = true;
btnNext.Enabled = true;
btnPrev.Enabled = true;
btnLast.Enabled = true;
if (this.BindingContext[mDataSet, "SelfInfo"].Position == 0)
{
btnPrev.Enabled = false;
btnFirst.Enabled = false;
}
if (this.BindingContext[mDataSet, "SelfInfo"].Position == (this.BindingContext[mDataSet,"SelfInfo"].Count-1))
{
btnNext.Enabled = false;
btnLast.Enabled = false;
}
}
由于在窗体打开的时候就需要设定按钮状态,所以在窗体的Load事件中调用此方法。
private void SelfDetail_Load(object sender, EventArgs e)
{
ButtonStateControl();
}
下面要对数据集导航的4个按钮进行编码,实现记录指针的移动,代码如下:
private void btnFirst_Click(object sender, EventArgs e)
{
this.BindingContext[mDataSet, "SelfInfo"].Position = 0;
ButtonStateControl();
}
private void btnPrev_Click(object sender, EventArgs e)
{
this.BindingContext[mDataSet, "SelfInfo"].Position -= 1;
ButtonStateControl();
}
private void btnNext_Click(object sender, EventArgs e)
{
this.BindingContext[mDataSet, "SelfInfo"].Position += 1;
ButtonStateControl();
}
private void btnLast_Click(object sender, EventArgs e)
{
this.BindingContext[mDataSet, "SelfInfo"].Position = this.BindingContext[mDataSet,"SelfInfo"].Count-1;
ButtonStateControl();
}
实验结果:
B.自己思考
1.修改程序,以编程方式实现DataSet和DataAdapter等数据控件的创建。
创建数据集DataSet:
DataSet myst=new DataSet();
创建sqlDataAdapter(与sqlCommand一起使用提高总体性能):
SqlDataAdapter myda;
SqlCommand command=new SqlCommand(sql,sqlcon);
Myda=new SqlDataAdapter(Command);
2.修改程序,实现当双击DataGridView控件的每一行记录时,弹出该学生个人明细信息窗口功能。
代码:
private void dgvAllStu_RowHeaderMouseDoubleClick(object sender, DataGridViewCellMouseEventArgs e)
{
frmSelf = new SelfDetail();
//获得选中的记录行
DataGridViewRow dgvRow = dgvAllStu.Rows[e.RowIndex];
//取出当前行单元格集合
DataGridViewCellCollection dgvAA = dgvRow.Cells;
frmSelf.Text = dgvAA[1].Value.ToString();
frmSelf.lblStudentNo.Text = dgvAA[0].Value.ToString();
frmSelf.tbBirthday.Text = dgvAA[3].Value.ToString();
frmSelf.txtMajor.Text = dgvAA[4].Value.ToString();
frmSelf.txtCredit.Text = dgvAA[5].Value.ToString();
frmSelf.txtInfor.Text = dgvAA[6].Value.ToString();
frmSelf.Show();
}
运行截图(由于先完成了第3小题,所以此时SelfDetail窗体已修改):
在运行时提醒这三个信息受到保护,无法显示。之后修改Modifiers属性即可。
双击张琳同学所在行:
3.使用上面介绍的方法,在明细窗口中增加显示数据库中某学生的其他一些个人专项信息,如学生所在专业、总学分、备注信息等。
SelfDetail窗体修改:
调整原来窗体内控件的位置,并增加3个Label控件和3个TextBox控件,调整位置,由于备注信息可能多行,所以设置该控件的Multiline属性为True,并需要将三个TextBox的Modifiers属性设置为public。如下图。
代码修改:
private void btnGRMX_Click(object sender, EventArgs e)
{
using (SqlConnection sqlcon = new SqlConnection(strcon))
{
sqlcon.Open();
//下面开始个人明细查询,并将查询生成的表SelfInfo与窗口frmSelf的数据集mdataSet同步绑定
string sql = "Select XH as'学号',XM as'姓名',CSRQ as'生日',ZY as'专业',BZ as'备注',ZXF as '总学分'from XSB";
SqlDataAdapter myda = new SqlDataAdapter(sql, sqlcon);
DataSet myst = new DataSet();
myda.Fill(myst, "SelfInfo");
frmSelf = new SelfDetail();
frmSelf.mDataSet = myst;
frmSelf.BindingContext = this.BindingContext;
frmSelf.DataBindings.Add("Text", myst, "SelfInfo.姓名");
frmSelf.lblStudentNo.DataBindings.Add("Text", myst, "SelfInfo.学号");
frmSelf.tbBirthday.DataBindings.Add("Text", myst, "SelfInfo.生日");
frmSelf.txtMajor.DataBindings.Add("Text", myst, "SelfInfo.专业");
frmSelf.txtCredit.DataBindings.Add("Text", myst, "SelfInfo.总学分");
frmSelf.txtInfor.DataBindings.Add("Text", myst, "SelfInfo.备注");
frmSelf.Show();
}
}
试验结束啦!!😎✌🤦♀️🤣😂🙌😃✨😆🎁❤😍🤞💕💋🌹😜👏😘👀💖😉😁😊