利用C#在做应用时偶然间发现的关于DataGridView的问题。下面是一个Demo。
窗口界面如图:后台代码如下:using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        SqlDataAdapter sqlDA;
        DataTable dt;
        public Form1()
        {
            InitializeComponent();
        }        private void btnModify_Click(object sender, EventArgs e)
        {
            dgv.CurrentCell.Value = "123";
            DataRowView drv = (DataRowView)dgv.CurrentRow.DataBoundItem;
            MessageBox.Show(drv.Row.RowState.ToString());
        }        private void Form1_Load(object sender, EventArgs e)
        {
            string strConn = "Data Source=192.168.1.110;Initial Catalog=GD-Pipe;Persist Security Info=True;User ID=sa;Password=123";
            sqlDA = new SqlDataAdapter("SELECT * FROM ModelType", new SqlConnection(strConn));
            SqlCommandBuilder sqlCB = new SqlCommandBuilder(sqlDA);
            dt = new DataTable();
            sqlDA.Fill(dt);            dgv.DataSource = dt;
        }
    }
}点击“修改”按钮后,DataGridView和绑定在上面的DataTable中的所对应的值都改变了,可是DataTable中的RowState依然是Unchanged,这是怎么回事呢?
环境:VS2010,SQL2008
DataGridView

解决方案 »

  1.   

    你没有修改DataTable里的值,你修改的是DataGridView某单元格的值。
      

  2.   

    我试了一下,DataTable中的值确实是改了的,结果也是123.
      

  3.   

    可能与这句有关SqlCommandBuilder sqlCB = new SqlCommandBuilder(sqlDA);我这里测试了显示的是Modify我是new一个DataTable,添加列和行,然后执行dt.AcceptChanges()。单击按钮后修改的代码跟你完全一样,弹出的是Modify。
      

  4.   

    贴一下你的代码看看吧。什么时候执行dt.AcceptChanges(),执行之后,DataTable里面所有行的RowState不都变成Unchanged么。
    我还发现在首次修改某条记录时会是Unchanged,在第二次修改时则变为Modified了。
      

  5.   

    datagridview貌似要回车移动到下一行才算提交这一行吧。提交之后才会改变状态,
    你这还是属于还在编辑中吧。
      

  6.   

    我试了一下,当前单元格并未处于编辑状态,并且运行时修改单元格的值并不会触发CellBeginEdit和CellEndEdit事件。如图:这个问题的关键是:修改了DataGridView中某单元格的值后,处于内存中的DataTable的值也发生了变化,但是其RowState却没有改变,这很奇怪啊。
      

  7.   

    谢谢dalmeeme和lye2000000_super的热心回答,我发现DataGridView具有一个属性IsCurrentRowDirty,表示当前行是否具有未提交的值。当dgv.CurrentCell.Value = "123"时,DataGridView并没有提交更改,所以DataTable中改行的RowState为Unchanged。因此,如果需要在运行时修改DataGridView中的单元格的值,则需要先dgv.StartEdit();在修改完成后,dgv.EndEdit();这样DataGridView就会将未提交的更改进行提交,内存中的DataTable也就接收到了这个修改,然后将RowState改为Modified。
    现在还有一个问题,就是DataTable中的数据值的发生改变,是不是其RowState也会随之更改?现在看来问题的答案是否定的,因为修改DataGridView中的值后,DataTable中的值也修改了,但是其RowState并为发生改变。我想这可能跟DataSet中的DataRelation有关系,MSDN上RowState的解释为“获取与该行和 DataRowCollection 的关系相关的当前状态”。到底是什么原因,我现在就没时间去看了,希望有知道的大神能给解释一下。
    好了,结贴。
      

  8.   

    这个地方我说的有错误,跟IsCurrentRowDirty属性没关系,但是在对DataGridView中的值进行修改时,确实应该先StartEdit(),然后EndEdit()。private void btnModify_Click(object sender, EventArgs e)
            {
                dgv.BeginEdit(false);
                dgv.CurrentCell.Value = "123";
                dgv.EndEdit();
                MessageBox.Show(dgv.IsCurrentRowDirty.ToString());
            }
      

  9.   

    按照以下方式可以达到你的要求:
    private void btnModify_Click(object sender, EventArgs e)
            {            
                if (dgv.CurrentCell != null)
                {
                    dgv.CurrentCell.Value = "123";
                    DataRowView drv = dgv.CurrentCell.OwningRow.DataBoundItem as DataRowView;
                    //这句是重点
                    drv.Row.EndEdit();
                }
            }