C# 用户更改单元格值时要捕获的DataGridView事件

C# 用户更改单元格值时要捕获的DataGridView事件,c#,winforms,datagridview,C#,Winforms,Datagridview,我有一个用C#编写的Winforms应用程序 在我的一个DataGridView中,除了一个名为“Reference”的列外,我已将所有列设置为ReadOnly=true 我希望应用程序知道用户何时更改了“Reference”列中的任何内容,但到目前为止,我尝试过的所有事件都比用户更改时触发的事件多得多。例如,当DataGridView最初呈现时,CurrentCellChanged会激发,每次用户只需单击或沿行添加选项卡等 我只对在“Reference”列中捕捉用户对数据的更改感兴趣,这是Re

我有一个用C#编写的Winforms应用程序

在我的一个DataGridView中,除了一个名为“Reference”的列外,我已将所有列设置为ReadOnly=true

我希望应用程序知道用户何时更改了“Reference”列中的任何内容,但到目前为止,我尝试过的所有事件都比用户更改时触发的事件多得多。例如,当DataGridView最初呈现时,CurrentCellChanged会激发,每次用户只需单击或沿行添加选项卡等

我只对在“Reference”列中捕捉用户对数据的更改感兴趣,这是ReadOnly=false的唯一列


哪一个事件是用于此的最佳事件?

CellValueChanged
是您需要的:

private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e){
  if(dataGridView1.Columns[e.ColumnIndex].Name == "Reference"){
    //your code goes here
  }
}
我认为事件
CellEndEdit
也适合您的需要:

private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e){
  if(dataGridView1.Columns[e.ColumnIndex].Name == "Reference"){
    //your code goes here
  }
}

在我的例子中,当DGV初始化时,CellValueChanged事件也会触发,所以我想使用CellEndEdit,正如King在回答中提到的那样

要使的第二个答案更加防弹(请参阅的注释),即仅作出反应,如果在单元格中输入了值,则可以执行以下操作:

   private void DataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
   {
        int? rowIdx = e?.RowIndex;
        int? colIdx = e?.ColumnIndex;
        if (rowIdx.HasValue && colIdx.HasValue)
        {
            var dgv = (DataGridView)sender;
            var cell = dgv?.Rows?[rowIdx.Value]?.Cells?[colIdx.Value]?.Value;
            if (!string.IsNullOrEmpty(cell?.ToString()))
            {
                // your code goes here
            };
        };
   }
       if (dgv.Columns[colIdx.Value].Name == "Reference")
       {
          if (!string.IsNullOrEmpty(cell?.ToString()))
          {
               // your code goes here
          };
       };
请注意使用
?。
?[
运算符进行的空处理。我编写了它,以便以更通用的方式使用它,但当然您可以添加对“Reference”列的检查,只需将上面的内部
if
语句替换为以下内容:

   private void DataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
   {
        int? rowIdx = e?.RowIndex;
        int? colIdx = e?.ColumnIndex;
        if (rowIdx.HasValue && colIdx.HasValue)
        {
            var dgv = (DataGridView)sender;
            var cell = dgv?.Rows?[rowIdx.Value]?.Cells?[colIdx.Value]?.Value;
            if (!string.IsNullOrEmpty(cell?.ToString()))
            {
                // your code goes here
            };
        };
   }
       if (dgv.Columns[colIdx.Value].Name == "Reference")
       {
          if (!string.IsNullOrEmpty(cell?.ToString()))
          {
               // your code goes here
          };
       };

我投票支持您的第二种解决方案:
private void dataGridView1_CellEndEdit(对象发送方,datagridviewcelleeventargs e){if(dataGridView1.Columns[e.ColumnIndex].Name==“Reference”){//您的代码在这里}
因为第一个解决方案在单元格中的值每次更改时都会触发,即使用户未触发该操作。例如,如果我有一个在后台添加行的方法,则会触发CellValueChanged。第二个解决方案(CellEndEdit事件)也会在值未更改时触发,例如,即使用户按下“esc”键要在不更改值的情况下结束编辑,@JPProgrammer-我找到了一种避免这种情况的方法,请参阅我对King的好答案的补充。