求教高手,很寸的问题,datagridview绑定datatable后在datagridview中删除行然后上下移动行出现问题

ytcola 2013-01-08 12:04:01
datagridview直接绑定datatable后。
下面 datagridview用dgv代替,dgv允许自动新增行,即:dgv.AllowUserToAddRows=true,datatable用dt代替
删除行按钮的代码:
if (dgv.CurrentCellAddress.Y >= 0 && dgv.CurrentRow.IsNewRow == false)
{
dgv.Rows.Remove(dgv.CurrentRow);
}
使用上面的代码,在dgv中就 真 删除了一行,同时这一行在dt中 假 删除了(只做了删除标记,而没有真的删除),dgv中的行索引和dt中的行索引就不一致了。
如果这个时候使用上下行移动代码:
向上移动行代码:
if (dgv.RowCount > 2 && dgv.CurrentRow.Index > 0 && dgv.CurrentRow.Index < dgv.RowCount - 1)
{
object[] _sourceRow = dt.Rows[dgv.CurrentRow.Index].ItemArray;
object[] _destRow = dt.Rows[dgv.CurrentRow.Index - 1].ItemArray;
dt.Rows[dgv.CurrentRow.Index].ItemArray = _destRow;
dt.Rows[dgv.CurrentRow.Index - 1].ItemArray = _sourceRow;
dgv.ClearSelection();
dgv.CurrentCell = dgv.Rows[dgv.CurrentRow.Index - 1].Cells[0];
}
向下移动代码
if (dgv.RowCount > 2 && dgv.CurrentRow.Index >=0 && dgv.CurrentRow.Index < dgv.RowCount - 2)
{
object[] _sourceRow = dt.Rows[dgv.CurrentRow.Index].ItemArray;
object[] _destRow = dt.Rows[dgv.CurrentRow.Index + 1].ItemArray;
dt.Rows[dgv.CurrentRow.Index].ItemArray = _destRow;
dt.Rows[dgv.CurrentRow.Index + 1].ItemArray = _sourceRow;
dgv.ClearSelection();
dgv.CurrentCell = dgv.Rows[dgv.CurrentRow.Index + 1].Cells[0];
}
如果没有删除行的存在,以上代码运绝对没有任何问题,但是在dgv中删除行后,因为行索引不一致了,所以上下移动行就出现了问题。比如在要上移或下移的记录的上一行删除了记录后就出现了错误。

如果删除事件采用dt中直接删除行:
dt.Rows.RemoveAt(dataGridView1.CurrentRow.Index);
这个时候上下移动行没有任何问题,但保存数据的时候因为删除行是直接在dt中删除的,这个删除动作不会在数据库中更新,也即这种删除的方法并不能使数据库中的数据也删除。

现在有什么办法让删除数据时dgv和dt中的行索引值保持一致又能更新数据呢?
求教各位高手!
...全文
348 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
lyx266 2014-05-04
  • 打赏
  • 举报
回复
我删除的时候是在在dt中删除 然后重新绑定一下,不然dgv和dt的行数对应不起来
於黾 2014-05-04
  • 打赏
  • 举报
回复
移动之前取一下标记不行么,如果要移动的位置已经被删除,就再移动一行..
yuyan1222 2014-05-04
  • 打赏
  • 举报
回复
楼主可以试试用DataView的RowStateFilter将已删除的行过滤掉,应该就可以对应上了。
carl_xie_87 2014-01-08
  • 打赏
  • 举报
回复
我觉得1楼说的方法非常好,你可以走第二条路呀
dong3580 2014-01-08
  • 打赏
  • 举报
回复
[quote=引用 楼主 ytcola 的回复:] datagridview直接绑定datatable后。 下面 datagridview用dgv代替,dgv允许自动新增行,即:dgv.AllowUserToAddRows=true,datatable用dt代替 删除行按钮的代码: if (dgv.CurrentCellAddress.Y >= 0 && dgv.CurrentRow.IsNewRow == false) { dgv.Rows.Remove(dgv.CurrentRow); } 使用上面的代码,在dgv中就 真 删除了一行,同时这一行在dt中 假 删除了(只做了删除标记,而没有真的删除),dgv中的行索引和dt中的行索引就不一致了。 如果这个时候使用上下行移动代码: 向上移动行代码: if (dgv.RowCount > 2 && dgv.CurrentRow.Index > 0 && dgv.CurrentRow.Index < dgv.RowCount - 1) { object[] _sourceRow = dt.Rows[dgv.CurrentRow.Index].ItemArray; object[] _destRow = dt.Rows[dgv.CurrentRow.Index - 1].ItemArray; dt.Rows[dgv.CurrentRow.Index].ItemArray = _destRow; dt.Rows[dgv.CurrentRow.Index - 1].ItemArray = _sourceRow; dgv.ClearSelection(); dgv.CurrentCell = dgv.Rows[dgv.CurrentRow.Index - 1].Cells[0]; } 向下移动代码 if (dgv.RowCount > 2 && dgv.CurrentRow.Index >=0 && dgv.CurrentRow.Index < dgv.RowCount - 2) { object[] _sourceRow = dt.Rows[dgv.CurrentRow.Index].ItemArray; object[] _destRow = dt.Rows[dgv.CurrentRow.Index + 1].ItemArray; dt.Rows[dgv.CurrentRow.Index].ItemArray = _destRow; dt.Rows[dgv.CurrentRow.Index + 1].ItemArray = _sourceRow; dgv.ClearSelection(); dgv.CurrentCell = dgv.Rows[dgv.CurrentRow.Index + 1].Cells[0]; } 如果没有删除行的存在,以上代码运绝对没有任何问题,但是在dgv中删除行后,因为行索引不一致了,所以quote] 每次都需要重新绑定数据源,记住一定要给每个字段做绑定的定义,不然就会移动变位了,
sd_wzl 2014-01-07
  • 打赏
  • 举报
回复
主要是数据没有接受对数据源更新的提交,当你使增 删 改后可以通过datatable的AcceptChanges()方法提交自上次调用AcceptChanges以来对该表进行的所有更改,也可以通过RejectChanges方法回滚操作。
ytcola 2013-01-08
  • 打赏
  • 举报
回复
每次删除一条数据就手动执行以下delete语句,如果大量删除的话跟数据库的操作就太频繁了,这个方法我想过,但是我觉得应该有更简单的方法实现吧。微软不至于这么笨吧,留下这么一个bug
wlzhn2012 2013-01-08
  • 打赏
  • 举报
回复
为什么不在删除的时候直接操作数据库把数据也删除了呢
ytcola 2013-01-08
  • 打赏
  • 举报
回复
wanghui0380 老大,你说的方法我试了,网上也有,不行的,干嘛要拖动BindingNavigator呢,BindingNavigator是数据的行一行一行的移动显示,而我的问题是在一个datagridview中上下移动行记录的相对位置啊。BindingNavigator并没有这个功能啊?
stonespace 2013-01-08
  • 打赏
  • 举报
回复
这个问题看得我发晕,
wanghui0380 2013-01-08
  • 打赏
  • 举报
回复
我想说的把你的代码全删干净,一行不留。 然后直接拖动一个BindingSource控件到form里 然后把BindingSource的DataSource属性设置为你的dt 接着把dgv的Datasource 设置为BindingSource; 剩下的事情,就要看你的态度了 如果你愿意让微软帮你自动完成,你可以继续拖动一个BindingNavigator到UI上,并且设置DataSouce为BindingSouce 如果你更愿意自己完成,那么就自己放控制按钮好了。比如下移一行,Bindingsouce.movenext,移除当前行 BindingSource.RemoveCurrent 这样你上面的界面功能基本都可以完成了 ===================================== 至于如何同步的数据库里面,这个首先取决与你最早和dt相关的适配器adapter是否设置了相关detelecommand,Updatecommand ,InsertCommand 语句,如果已经设置,那么不必你做啥操作了,微软会自动更新你的修改到数据里面 如果你前面木有设置,则需订阅一下Bindingsouce的OnListChanged事件,在这个事件里获取相关操作状态和行信息,然后自己更新信息入库 ps:其实这块的东西在msdn的事例和演练里面都有,具体去看 http://msdn.microsoft.com/zh-cn/library/h974h4y2(v=vs.90).aspx 不过是设计演练的东西,很多是依靠直接设定数据库连接方式完成,玩OO滴觉着不靠谱,所以木流行开。但是这不表明,俺们不能使用代码使用OO,去利用这些微软已经做好的玩意,更方便的实现俺要实现的功能

110,535

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧