C#中的DataGridView控件(WIN FORM),数据绑定与数据联动

方法1:微软提供的DataGridView主从表显示示例
http://www.cnblogs.com/NETCCB/articles/1335347.html

优点:前台不用写代码,都由BindingSource等控件实现。

缺点:填充到数据集中的子表的所有记录必须在主表中有对应数据。

方法2:是在DataGridView.RowEnter中写类似如下代码,

labCusId.Text = dgvCustomer.CurrentRow.Cells[col].Value.ToString();

字段一多,这种方法就非常繁琐。


这里介绍另一种利用数据绑定实现数据联动的方法。

private void FillSaledgv(string CusIDStr)
{
	dgvSale.DataSource = null;
	DataSet sqlDS = new DataSet();
	sqlDataAda.Fill(sqlDS,"vw_SaleInfo");
	DataView sqlDV = sqlDS.Tables["vw_SaleInfo"].DefaultView;
	if (sqlDS.Tables["vw_SaleInfo"].Rows.Count > 0)
	{
		dgvSale.DataSource = sqlDV;
	}
	BindSaleTxt(sqlDV);
	sqlCon.Close();
}     


private void BindSaleTxt(DataView sqlDV)
{
	labSaleID.DataBindings.Clear();
	labSaleIDDetail.DataBindings.Clear();
	txtHWSaleIDDel.DataBindings.Clear();
	dtpSaleBillDate.DataBindings.Clear();


		if (sqlDV.Table.Rows.Count > 0)
	{
		labSaleID.DataBindings.Add("Text", sqlDV, "销售单ID");
		labSaleIDDetail.DataBindings.Add("Text", sqlDV, "销售单ID");
		txtHWSaleIDDel.DataBindings.Add("Text", sqlDV, "手工销售单号");
		dtpSaleBillDate.DataBindings.Add("Value", sqlDV, "销售日期");
	}
}


需要注意的是:dgvSale.DataSource = sqlDV; 和 BindSaleTxt(sqlDV);这里的数据源必须是一致的——如果是数据表,则必须是同一个表。
我之前是曾犯错误:
dgvSale.DataSource = sqlDS.Tables["vw_SaleInfo"];
BindSaleTxt(sqlDS.Tables["vw_SaleInfo"].DefaultView);

虽然各自能够取到数据,但labSaleID等显示控件不能随dgvSale联动。


Q:对于两个datagridView实现的数据联动,主datagridView绑定数据时selectionChanged事件发生多次,什么原因,如何避免?
A:selectionChanged事件MSDN上叙述:“在当前选择出现更改时发生。”
实际应用中,子表数据填充代码要写在selectionChanged事件响应方法中。
经测试,selectionChanged事件有如下规律:
SelectionChanged事件发生次数与触发方式和dataGridView中是否有数据有关。
1.由数据绑定触发,如果dataGridView中原来无数据,则SelectionChanged事件发生1次;(从没有选定行到有选定行。)
2.由数据绑定触发,如果dataGridView中原来有数据,则SelectionChanged事件发生2次;(取消选定行发生1次,选定新行发生1次。)
3.由用户(鼠标或键盘动作)触发,dataGridView中原来有数据,则SelectionChanged事件发生1次;


解决方法:设置一个开关变量
/// <summary>
/// 防止dgvIn数据绑定时发生多次SelectionChanged事件,设置开关变量
/// </summary>
private static byte SelectionChangedTimes;

每次数据绑定前设置开关变量的值
if (dgvIn.Rows.Count == 0)
SelectionChangedTimes = 1;  // 无数据直接跨过阀值
else
SelectionChangedTimes = 0;  // 有数据设定小于阀值
dgvIn.DataSource = dtIn;

// SelectionChanged中对开关变量进行判断,决定是否对子表进行数据绑定
private void dgvIn_SelectionChanged(object sender, EventArgs e)
{
if (++SelectionChangedTimes == 1)
return;
else
if (SelectionChangedTimes >= 255)
SelectionChangedTimes = 2;  // 防止数据越界


if (null != dgvIn.CurrentRow)
{
// 对子表进行数据绑定
}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值