一、在窗口中放置一个DataGridview控件,名称为dv
二、为DataGridView在设计器中添加两列:
列1:Name="sph_sph",HeaderText="编号",ColumnType=DataGridViewTextBoxColumn
列2:Name="sph_zt",HeaderText="状态",ColumnType=DataGridViewComboBoxColumn
三、继承DataTable,自定义一个DataTable,用来为DataGridView中的“状态”列显示下拉选项:
class DataList_sph_zt : DataTable
{
public DataColumn zt_value = null;
public DataColumn zt_display = null;
public DataList_sph_zt()
{
//为DataTable定义两列
zt_value = new DataColumn();
zt_display = new DataColumn();
zt_value.ColumnName = "value";
zt_display.ColumnName = "display";
zt_value.DataType = typeof(int);
zt_display.DataType = typeof(string);
//将列加入到DataTable
this.Columns.Add(zt_display);
this.Columns.Add(zt_value);
//加入下拉选项数据行
DataRow dr = this.NewRow();
dr["value"] = 0;
dr["display"] = "状态1";
this.Rows.Add(dr);
dr = this.NewRow();
dr["value"] = 1;
dr["display"] = "状态2";
this.Rows.Add(dr);
dr = this.NewRow();
dr["value"] = 2;
dr["display"] = "状态3";
this.Rows.Add(dr);
}
}
四、为窗口定义私有成员变量:
//存放数据的DataTable对象
private DataTable dataList = new DataTable();
//DataGridView中列sph_zt的下拉数据项所在的DataTable
private DataList_sph_zt sph_zt_list = new DataList_sph_zt();
//数据连接对象
private SqlConnection _connection = null;
//数据适配器对象,用来装载数据和更新数据库
private SqlDataAdapter sda = new SqlDataAdapter();
//数据适配器用来装载数据用的select语句
private string _sqlSelect = "";
//用来为数据适配器生成insert、delete、update语句的命令生成器对象
private SqlCommandBuilder scb = new SqlCommandBuilder();
//数据适配器的SelectCommand相关联的数据库命令对象
private SqlCommand sqlSelect = new SqlCommand();
//事务对象
SqlTransaction st = null;
五、为数据连接对象和select语句成员变量声明访问器,并用命令生成器为数据适配器对象生成数据库命令对象:
public SqlConnection Connection
{
get { return _connection; }
set
{
_connection = value;
//将新设置的数据连接对象关联到数据库命令对象上
sqlSelect.Connection = _connection;
}
}
public string SqlSelect
{
get { return _sqlSelect; }
set
{
//如果新设置的select查询语句与原来的不同,则将_sqlSelect成员变量设为新值。
if (_sqlSelect != value)
{
_sqlSelect = value;
//则重新设置数据库命令对象的CommandText属性
//并为数据适配器对象重新生成InsertCommand、DeleteCommand和UpdateCommand
sqlSelect.CommandText = _sqlSelect;
scb.RefreshSchema();
sda.InsertCommand = scb.GetInsertCommand();
sda.DeleteCommand = scb.GetDeleteCommand();
sda.UpdateCommand = scb.GetUpdateCommand();
}
}
}
六、在窗口的构造函数中设置各个对象的属性:
//系统定义的初始化函数
InitializeComponent();
//设置DataGridView控件的数据源为DataTable对象dataList
dv.DataSource = dataList;
//设置DataGridView控件的各列关联的源数据列对象
sph_sph.DataPropertyName = "sph_sph";
sph_zt.DataPropertyName = "sph_zt";
//设置列sph_zt下拉项关联的数据源对象
sph_zt.DataSource = sph_zt_list;
sph_zt.ValueMember = "value";
sph_zt.DisplayMember = "display";
//设置数据适配器的SelectCommand为sqlSelect成员变量
sda.SelectCommand = sqlSelect;
//设置命令生成器关联的数据适配器对象
scb.DataAdapter = sda;
七、装载数据到DataGridView
public void retrieve()
{
//清除DataGridView的所有行
dataList.Rows.Clear();
//打开数据库连接
_connection.Open();
//填充DataTable数据
sda.Fill(dataList);
//关闭数据库连接
_connection.Close();
}
八、得到DataGridView当前行(按照个人习惯,将实际的行号(从零开始)加1,让它从1开始):
public int getRow()
{
if (this.dv.Rows.Count > 0 && this.dv.CurrentRow.Index >= 0)
return this.dv.CurrentRow.Index + 1;
else
return 0;
}
九、删除DataGridView指定行(传入的row是实际行号加1,还是个人习惯):
public void deleteRow(int row)
{
if (row <= 0 || row > this.dv.Rows.Count)
return;
//用DataGridViewrow的DataBoundItem属性得到当前绑定的原始数据行,是一个DataRowview对象
//再用这个对象得到对应的DataRow
(dv.Rows[row - 1].DataBoundItem as DataRowView).Row.Delete()
}
十、在DataGridView最后新增一行
public void insertRow()
{
DataRow dr = dataList.NewRow();
//为新行指定内容
//dr["sph_sph"] = "";
//dr["sph_zt"] = 0;
dataList.Rows.Add(dr);
//指定DataGridView当前行为最后一行,即新增的行
dv.CurrentCell = this.dv.Rows[this.dv.Rows.Count - 1].Cells[0];
}
十一、将对DataGridView数据的修改更新到数据库
public void update()
{
//打开数据库连接
_connection.Open();
//开始一个事务
st = _connection.BeginTransaction();
//将事务对象关联到数据适配器的数据库命令对象
sda.InsertCommand.Transaction = st;
sda.DeleteCommand.Transaction = st;
sda.UpdateCommand.Transaction = st;
//更新到数据库
sda.Update(dataList);
//提交事务,应捕获异常,如果发生异常则需要用st.Rollback回滚事务
st.Commit();
//关闭数据库连接
_connection.Close();
}
十二、后记
1、在用命令生成器为数据适配器生成数据库命令对象时,必须至少首先为数据适配器指定SelectCommand对象。
2、如果更改了数据适配器的SelectCommand对象的CommandText属性,则应该重新为数据适配器生成数据库命令对象,应先调用命令生成器的RefreshSchema()方法清除旧的命令对象。
3、如果用事务控制适配器对数据库数据的更新,应该在命令生成器已经为适配器生成所有命令对象之后,用数据库连接对象的BeginTransaction()方法生成一个事务对象,然后将这个事务对象赋值给数据适配器的所有命令对象的Transaction属性。在调用数据适配器的Update()方法后调用事务对象的Commit()方法来提交事务或在发生异常时调用事务对象的Rollback()方法来回滚事务。