DataGridView编辑Datatable记录,多空白行

一、描述

习惯了BS开发,今天对数据DataTable的DataGridView进行增删改查。遇到一下空白行的问题,记录一下。

二、操作

在这里插入图片描述在这里插入图片描述

dg1.AutoGenerateColumns = false;//不自动显示数据库中未绑定的列
dg1.DataSource = dt;

绑数据、开编辑、设定列;

三、操作

private void dg1_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
{
  DataGridViewRow Row = dg1.Rows[e.RowIndex];//操作行
  string dataName = dg1.Columns[e.ColumnIndex].DataPropertyName;//列数据名
  string id = Row.Cells[1].Value.ToString().Trim();//数据唯一标识
   //记录改动
   DataRow _row = dt.AsEnumerable().Where(p => p["id"].ToString() == id).FirstOrDefault();
   if (_row==null)//新增行
   {
     _row = dt.NewRow();
     dt.Rows.Add(_row);//加行
     //临时ID
     int rowcount = dt.Rows.Count;
     string _id = $"-{rowcount}";
     _row["id"] = _id;
   }
   _row[dataName] = e.FormattedValue.ToString().Trim();//当前单元格值
}

运行效果
在这里插入图片描述
录入11,失去焦点后执行CellValidating,
多了两行空白,愁

PS:我想会不会是dt更新 也触发了本函数,
函数头加个lock,函数尾释放,防执行中被触发,失败!

四、改动1

刷新dt之前禁用行自增AllowUserToAddRows,完事再启用

private void dg1_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
{
  DataGridViewRow Row = dg1.Rows[e.RowIndex];//操作行
  string dataName = dg1.Columns[e.ColumnIndex].DataPropertyName;//列数据名
  string id = Row.Cells[1].Value.ToString().Trim();//数据唯一标识
   //记录改动
  DataRow _row = dt.AsEnumerable().Where(p => p["id"].ToString() == id).FirstOrDefault();
  dg1.AllowUserToAddRows = false; //--关
   if (_row==null)//新增行
   {
     _row = dt.NewRow();
     dt.Rows.Add(_row);//加行
     //临时ID
     int rowcount = dt.Rows.Count;
     string _id = $"-{rowcount}";
     _row["id"] = _id;
   }
   _row[dataName] = e.FormattedValue.ToString().Trim();//当前单元格值
   dg1.AllowUserToAddRows = true;//--开
}

运行效果:
在这里插入图片描述
录入11,多了一行,应该是CellValidating所在的ROW无法释放。dt.Rows.Add 数据刷新 又触发了Gridview行编辑的提交。

五、改动2

加一个DataTable做数据缓存。以作后期提交。将页面、数据分开

 dt2 = dt.Copy();//定义一个缓存区
 ---
 private void dg1_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
{
  DataGridViewRow Row = dg1.Rows[e.RowIndex];//操作行
  string dataName = dg1.Columns[e.ColumnIndex].DataPropertyName;//列数据名
  string id = Row.Cells[1].Value.ToString().Trim();//数据唯一标识
  //记录改动
  DataRow _row = dt2.AsEnumerable().Where(p => p["id"].ToString() == id).FirstOrDefault();
  dg1.AllowUserToAddRows = false; //--关
   if (_row==null)//新增行
   {
     _row = dt2.NewRow();
     dt2.Rows.Add(_row);//加行
     //临时ID
     int rowcount = dt.Rows.Count;
     string _id = $"-{rowcount}";
     _row["id"] = _id;
     Row.Cells[0].Value = _id;//这句的加上了
   }
   _row[dataName] = e.FormattedValue.ToString().Trim();//当前单元格值
 dg1.AllowUserToAddRows = true;//--开
}
 

运行成功
在这里插入图片描述
这次对了,
因为编辑和数据的暂时性差异(Grid会新增行,换行后,整行提交到数据。这期间这条在数据中不存在)

六、问题背后的思考

1、Gridview 绑定数据源,增删查改都很灵活,用DataTable就麻烦一些,很多自带的功能无法实现,比如当前行添加撤销(监听占用当前行)

2、Gridview 是行提交。而DataTable必须列提交。所以注定了数据上暂时的差异。
Grid是缓存一行,失去焦点提交到数据源或DataTable,
DataTable是即时的,行第一格录入不建DataRow,第二格录入就没操作行对象。
而dt.Rows.add后的数据刷新(第1行),会造成Grid新行中断编辑、提交数据(第2行),就会多一行。

3、AllowUserToAddRows是grid 新增行功能,底部会多一行空白,dt.Rows.add如上所说会加两行新增,所以就会有3行新增,这是在CellValidating监听之外的,无法避免。

4、既然grid和dt只能单方面数据同步,所以最终我使用第2个dt作为数据保存副本,之后从逻辑上去避免作业中dt和dt2的最终差异,并使用dt2作为提交到数据库的改动依据。

七、后记

今天偶然用了另外一种思路,成功规避了空白行的生成。
提前在datatable内加入空行,使grid被动加行。避免grid单方面加行后、到行提交前的与datatable的差异。

private void dg1_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
{
    if (e.RowIndex >= 0)
    {
        int row = e.RowIndex;
        int column = e.ColumnIndex;
        if (column < 0) column = 0;
        //无值,添加空行
        if (dg1.Rows[row].Cells[1].Value == null)
        {
            DataRow dr = dt.NewRow();
            int rowcount = dt.Rows.Count + 1;
            string _id = $"-{rowcount}";
            //行赋值
            dr["name"] = "";
            dr["id"] = _id;
            dr["model"] = "";
            dr["brand"] = "";
            dr["salepc"] = 0;
            dr["counts"] = "1";
            dt.Rows.Add(dr);
        }
        dg1.ClearSelection();
        //右键菜单
        //if (e.Button == MouseButtons.Right)
        // {
        //dg1.CurrentCell = dg1.Rows[row].Cells[column];//更改当前行-焦点变更
        //this.cttMenu_dg1.Show(Control.MousePosition);//菜单加到右键  这里做移除右键菜单的ContentStripMenu
        // }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值