C# InvalidOperationException-结束编辑单元格并移动到另一个单元格时
我制作了一个程序,希望手动更新数据网格视图。 -我有一种刷新DGV的方法,方法是清除DGV,然后重新插入数据。 -使用设计器,我为DGV的CellEndEdit创建了一个事件处理程序。在事件处理程序中,数据得到更新&调用DGV的自定义刷新方法 运行程序时,每当我开始编辑单元格并通过选择另一个单元格结束时,都会引发异常: 无效操作例外 操作无效,因为它导致对SetCurrentCellAddressCore函数的可重入调用 Visual C的调试器标记清除数据的行:datagridview1.Rows.Clear 如果要重现此问题,请使用visual c创建新的windows窗体项目,在窗体上放置DataGridView对象,然后为Form1.cs粘贴以下代码:C# InvalidOperationException-结束编辑单元格并移动到另一个单元格时,c#,datagridview,invalidoperationexception,C#,Datagridview,Invalidoperationexception,我制作了一个程序,希望手动更新数据网格视图。 -我有一种刷新DGV的方法,方法是清除DGV,然后重新插入数据。 -使用设计器,我为DGV的CellEndEdit创建了一个事件处理程序。在事件处理程序中,数据得到更新&调用DGV的自定义刷新方法 运行程序时,每当我开始编辑单元格并通过选择另一个单元格结束时,都会引发异常: 无效操作例外 操作无效,因为它导致对SetCurrentCellAddressCore函数的可重入调用 Visual C的调试器标记清除数据的行:datagridview1.Ro
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace Error___DataGridView_Updating___Cell_endedit
{
public partial class Form1 : Form
{
// Objects
DataTable dt;
DataColumn colID;
DataColumn colName;
DataColumn colInfo;
// Constructor
public Form1()
{
InitializeComponent();
Initialize_dt();
InsertSampleData_dt();
Initialize_dataGridView1();
}
// Methods
private void Initialize_dt()
{
dt = new DataTable();
// Building Columns
// ID
colID = new DataColumn();
colID.ColumnName = "ID";
colID.DataType = typeof(int);
dt.Columns.Add(colID);
// Name
colName = new DataColumn();
colName.ColumnName = "Name";
colName.DataType = typeof(string);
dt.Columns.Add(colName);
//Info
colInfo = new DataColumn();
colInfo.ColumnName = "Info";
colInfo.DataType = typeof(string);
dt.Columns.Add(colInfo);
}
private void InsertSampleData_dt()
{
DataRow row;
// 0
row = dt.NewRow();
row["ID"] = 100;
row["Name"] = "AAAA";
row["Info"] = "First Record";
dt.Rows.Add(row);
//1
row = dt.NewRow();
row["ID"] = 101;
row["Name"] = "BBBB";
row["Info"] = "Second Record";
dt.Rows.Add(row);
//2
row = dt.NewRow();
row["ID"] = 102;
row["Name"] = "CCCC";
row["Info"] = "Third Record";
dt.Rows.Add(row);
}
private void Initialize_dataGridView1()
{
dataGridView1.AllowUserToAddRows = false;
// Data Grid Definitions
// Row Header
dataGridView1.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.DisableResizing;
dataGridView1.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders;
// ColumnHeaders
dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
// Building Columns
#region ID
{
DataGridViewColumn colSGID = new DataGridViewTextBoxColumn();
colSGID.Name = "ID";
colSGID.HeaderText = "#";
colSGID.ReadOnly = true;
colSGID.Visible = false;
colSGID.Resizable = DataGridViewTriState.False;
dataGridView1.Columns.Add(colSGID);
}
#endregion
#region Name
{
DataGridViewColumn colSGName = new DataGridViewTextBoxColumn();
colSGName.Name = "Name";
colSGName.HeaderText = "Name";
dataGridView1.Columns.Add(colSGName);
}
#endregion
#region Info
{
DataGridViewColumn colSGSubject = new DataGridViewTextBoxColumn();
colSGSubject.Name = "Info";
colSGSubject.HeaderText = "Description";
dataGridView1.Columns.Add(colSGSubject);
}
#endregion
Refresh_dataGridView1();
}
private void Refresh_dataGridView1()
{
int index;
dataGridView1.SuspendLayout();
dataGridView1.Rows.Clear();
//MessageBox.Show("Cleared Data. Rebuilding...");
foreach (DataRow row in dt.Rows)
{
index = dataGridView1.Rows.Add(new DataGridViewRow());
dataGridView1.Rows[index].Cells["ID"].Value = row["ID"];
dataGridView1.Rows[index].Cells["Name"].Value = row["Name"];
dataGridView1.Rows[index].Cells["Info"].Value = row["Info"];
//MessageBox.Show("row #" + index);
}
dataGridView1.ResumeLayout();
}
//Event Handlers
private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
bool toUpdate = false;
int id = (int)dataGridView1.Rows[e.RowIndex].Cells["ID"].Value;
string columnName = dataGridView1.Columns[e.ColumnIndex].Name;
string value = (string)dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value;
if (value == null)
{
value = string.Empty;
}
switch (columnName)
{
case "Name":
if (value == string.Empty)
{
MessageBox.Show("Name Can't Be Empty!");
}
else
{
toUpdate = true;
}
break;
case "Info":
toUpdate = true;
break;
}
if (toUpdate)
{
foreach(DataRow row in dt.Rows)
{
if ( (int)row["ID"] == id)
{
row[columnName] = value;
}
}
Refresh_dataGridView1();
}
}
}
}
这是Bruce.Zhou在MSDN论坛上的回答。我在这里贴了一段。也就是原始帖子的链接
private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
...................................................;
if (toUpdate)
{
foreach(DataRow row in dt.Rows)
{
if ( (int)row["ID"] == id)
{
row[columnName] = value;
}
}
this.BeginInvoke(new MethodInvoker(Refresh_dataGridView1));
}
}
使用此修复时,无论何时选择新单元格,都会选择它与第一个单元格之间的所有单元格(包括)。我正在寻找一种只选择新单元格的方法。为了解决这个问题,我在最后一个小时用头敲击键盘。 以下是我的解决方法: 查看问题:在gridview中选择另一个单元格或任何控件时,会触发EndEdit 在应用编辑之前,请应用以下检查:
public void myGrid_EndEdit(object sender, DataGridViewCellEventArgs e)
{
if (!myGrid.Rows[e.RowIndex].Cells[e.ColumnIndex].Selected)
return;
//...rest of your code to apply edit below...
}
这应适用于任何正在编辑的单元格。因此,失去焦点时不应用编辑;键入Enter就足以应用编辑了,我的工作是捕获CellMouseDown事件,如果操作发生在正在编辑的单元格以外的单元格上,则会发出DataGridView.EndEdit。其他一切正常。忘了提及。粘贴代码后,运行程序并执行以下操作:2单击选定的单元格。3再次单击该单元格,进入编辑模式。4选择其他单元格单元格结束编辑事件发生,应立即引发异常。我了解您的问题。。。但我不明白你想要实现什么。。。请详细说明。据我所知,您正在尝试更新单元格值。。。是的,我正在尝试使用数据网格视图*更新数据表中的单元格值。我手动绑定数据网格视图,以便能够更好地控制哪些值可以允许,哪些值不能允许*然而,在我的实际项目中,我正在使用表适配器更新类型化数据集