InvalidOperationException - 当编辑单元格&移动到另一个单元格 [英] InvalidOperationException - When ending editing a cell & moving to another cell

查看:121
本文介绍了InvalidOperationException - 当编辑单元格&移动到另一个单元格的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我制作了一个我想手动更新数据网格视图的程序。
- 我有一个方法来清除DGV,然后重新插入数据。
- 使用设计器,我为DGV的CellEndEdit创建了一个事件处理程序。在事件处理程序内,数据更新&调用DGV的自定义刷新方法。



在运行程序时,每当我开始编辑单元格&通过选择另一个来终止它,抛出异常:



InvalidOperationException
操作无效,因为它导致对SetCurrentCellAddressCore函数的重入调用。 p>

Visual C#的调试器标记清除数据的行:datagridview1.Rows.Clear();



d想重现问题,使用visual c#创建一个新的窗体项目,在表单上放置一个DataGridView对象,并粘贴Form1.cs的以下代码:

 使用系统; 
使用System.Collections.Generic;
使用System.ComponentModel;
使用System.Data;
使用System.Drawing;
使用System.Linq;
使用System.Text;
使用System.Windows.Forms;

命名空间Error___DataGridView_Updating___Cell_endedit
{
public partial class Form1:Form
{
//对象
DataTable dt;
DataColumn colID;
DataColumn colName;
DataColumn colInfo;
//构造函数
public Form1()
{
InitializeComponent();

Initialize_dt();
InsertSampleData_dt();
Initialize_dataGridView1();
}

//方法
private void Initialize_dt()
{
dt = new DataTable();

//建立列
// ID
colID = new DataColumn();
colID.ColumnName =ID;
colID.DataType = typeof(int);
dt.Columns.Add(colID);

//名称
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;

//数据网格定义
//行标题

dataGridView1.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.DisableResizing;
dataGridView1.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders;
// ColumnHeaders
dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;

//构建列
#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名称
{
DataGridViewColumn colSGName = new DataGridViewTextBoxColumn();
colSGName.Name =Name;
colSGName.HeaderText =Name;

dataGridView1.Columns.Add(colSGName);
}
#endregion

#region信息
{
DataGridViewColumn colSGSubject = new DataGridViewTextBoxColumn();
colSGSubject.Name =Info;
colSGSubject.HeaderText =描述;

dataGridView1.Columns.Add(colSGSubject);
}
#endregion

Refresh_dataGridView1();
}

private void Refresh_dataGridView1()
{
int index;

dataGridView1.SuspendLayout();

dataGridView1.Rows.Clear();

//MessageBox.Show(Cleared Data。Rebuilding ...);

foreach(dt.Rows中的DataRow行)
{
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();
}

//事件处理程序
private void dataGridView1_CellEndEdit(object sender,DataGridViewCellEventArgs e)
{
bool toUpdate = false;

int id =(int)dataGridView1.Rows [e.RowIndex] .Cells [ID]。
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)
{
caseName:
if(value == string.Empty)
{
MessageBox.Show(名称不能为空!);
}
else
{
toUpdate = true;
}
break;
caseInfo:
toUpdate = true;
break;


if(toUpdate)
{
foreach(dt.Rows中的DataRow行)
{
if((int)row [ID] == id)
{
row [columnName] = value;
}
}

Refresh_dataGridView1();
}

}
}
}


解决方案

在MSDN论坛上有一个Bruce.Zhou的答案。我在这里张贴了一个片段。 这里也是链接到原始帖子。

  private void dataGridView1_CellEndEdit(object sender,DataGridViewCellEventArgs e)
{
。 .................................................. ;
if(toUpdate)
{
foreach(dt.Rows中的DataRow行)
{
if((int)row [ID] == id)
{
row [columnName] = value;
}
}

this.BeginInvoke(new MethodInvoker(Refresh_dataGridView1));
}
}




...


当使用此修补程序时,每当选择新单元格时,将选择它和第一个单元格(包括)之间的所有单元格。我正在寻找一种只选择新单元格的方法。


I made a program in which I wanted to manually update the Data Grid View. -I have a Method to Refresh the DGV by clearing it and then reinserting the data. -Using the designer, I made an event handler for the DGV's CellEndEdit. Inside the Event Handler, the data gets updated & the DGV's custom refreshing method is called.

While running the program, whenever I start editing a cell & end it by selecting another one, an exception is thrown:

InvalidOperationException Operation is not valid because it results in a reentrant call to the SetCurrentCellAddressCore function.

Visual C#'s debugger marks the line that clears the data : datagridview1.Rows.Clear();

If you'd like to reproduce the problem, Make a new windows form project with visual c#, put a DataGridView object on the form, and paste the following code for the Form1.cs:

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();
            }

        }
    }
}

解决方案

There's an answer by Bruce.Zhou at MSDN forums. I posted here a snippet from it. Here also is the link to the original post.

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));
    }
}

...

When using this fix, whenever the new cell is selected, all the cells between it and the first cell (including) are selected. I am looking for a way to select only the new cell.

这篇关于InvalidOperationException - 当编辑单元格&移动到另一个单元格的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆