添加行时,DataGridView抛出“InvalidOperationException:Operation无效…”

我想在用户点击单元格时出现OpenFileDialog,然后在单元格中显示结果。

这一切都有效,除了DataGridView显示一个额外的行,用于将值添加到它所绑定的列表中。 如果dataGridView.AllowUserToAddNewRows == true ,则显示该行,这就是我想要的。 我不想要的是当以编程方式编辑该行时应用程序崩溃; 相反,它应该完全按照用户手动编辑该行的方式执行(将新行添加到基础列表,将另一个空行推入网格以添加值)。

我读到了SendKeys.Send(),它应该使DataGridView的行为与用户输入的值完全相同; 但是,它也不起作用。 这是我正在尝试的:

 if (openFileDialog1.ShowDialog() == DialogResult.OK) { dataGridView1.CurrentCell = cell; //simply doing a cell.Value = etc. will cause the program to crash cell.ReadOnly = false; dataGridView1.Columns[cell.ColumnIndex].ReadOnly = false; dataGridView1.EditMode = DataGridViewEditMode.EditOnEnter; dataGridView1.BeginEdit(true); SendKeys.Send(openFileDialog1.FileName + "{Enter}"); dataGridView1.EndEdit(); cell.ReadOnly = true; dataGridView1.Columns[cell.ColumnIndex].ReadOnly = true; } //I would expect the FileName would be in the cell now, and a new empty //row tacked onto the end of the DataGridView, but it's not; the DataGridView //is not changed at all. 

当我尝试使用绑定源编程编辑单元格时,我遇到了同样的问题。 “”由于对象的当前状态,操作无效“

哪个操作? 什么状态? 非常有帮助。

除了编辑网格中的最后一行外,我的代码似乎工作正常。

原来关键是DataGridView.NotifiyCurrentCelldirty(true)

以编程方式编辑单元格的正确顺序,因此它的工作方式与用户执行的顺序相同。 (更改最后一行中的单元格时出现一个新的空行)是这样的:

1)使单元格编辑当前单元格(执行当前当前单元格所需的操作,首先如果它处于编辑模式则调用endEdit。)

2)调用DataGridview.BeginEdit(false)

3)调用DataGridView.NotifyCurrentCellDirty(true)

4)修改值。

5)调用DataGridView.EndEdit()

而且你想要为RowValidating和RowValidated事件做些什么。

我更新单元格值的例程之一如下所示:

这是从我的类派生自DataGridView的方法。 您可以从包含表单执行相同的操作,通过DataGridView实例调用,因为这些方法是公共的。 这里的电话使用了一个隐含的“这个”。

  private void EnterTime() { if (CurrentRow == null) return; SaveCurrentCell(); // Calls EndEdit() if CurrentCell.IsInEditMode DataGridViewCell previous = CurrentCell; CurrentCell = CurrentRow.Cells[CatchForm.TimeColumn]; BeginEdit(false); NotifyCurrentCellDirty(true); CurrentCell.Value = DateTime.Now; EndEdit(); CurrentCell = previous; } 

我不确定为什么需要单独的电话。

为什么BeginEdit或实际修改单元格值不会导致正确的事情发生?

如果您在实际修改单元格后将NotifyCurrentCellDirty调用移动到它,它也不会正常运行。 一切都很烦人。

我在这个页面上找到了一个解决方法,但我不知道它为什么有效

 public MyForm() { InitializeComponent(); //Create a BindingSource, set its DataSource to my list, //set the DataGrid's DataSource to the BindindingSource... _bindingSource.AddingNew += OnAddingNewToBindingSource; } private void OnAddingNewToBindingSource(object sender, AddingNewEventArgs e) { if(dataGridView1.Rows.Count == _bindingSource.Count) { _bindingSource.RemoveAt(_bindingSource.Count - 1); } } 

我非常厌倦了花这么多时间处理Visual Studio漏洞……

这是旧的,但我正在运行VS2010并且遇到了这个问题。 我有一个使用BindingList绑定到ListDataGridView 。 我在DataGridView上有一个拖放事件,它会删除DGV中的所有行(除了最后一个无法删除的空白除外) 之后抛出此exception, 然后通过DragDrop处理程序向DGV添加新行BindingList 。 如果我只是添加手动编辑单个单元格的行,则不会抛出此exception。

我读过的一个解决方案是处理BindingList.AddNew事件,但我发现在DragDrop事件处理程序中调用BindingList.Add()时这个事件没有触发(我不知道为什么)。 我通过添加解决了这个问题

 if(bindingList.Count == 0) bindingList.RemoveAt(0) 

将新对象添加到bindingList 之前 ,在DragDrop事件处理程序bindingList 。 当bindingList中唯一的“对象”是与最后一个空行相关联的对象时,似乎向bindingList添加一个对象失败了。 BindingList的要点是允许开发人员直接使用它而不是 DGV,但似乎这样做会导致边界情况出现问题。

DGV行和BindingList行之间的关系似乎有点像灰色区域。 我没有花太多时间研究这个,但我不清楚与DGV的最后(空)行相关联的BindingList中的“对象”的状态是什么。 但是,当您直接与最终行(而不是通过DataSource )交互时,它似乎只是“正确”实例化了“对象”。

试试这个:

  if (openFileDialog1.ShowDialog() == DialogResult.OK) { int row = e.RowIndex; int clmn = e.ColumnIndex; if(e.RowIndex == dataGridView1.Rows.Count- 1) dataGridView1.Rows.Add(); dataGridView1.Rows[row].Cells[clmn].Value = openFileDialog1.FileName; } 

编辑我没注意到你绑定了你的datagridview :(好吧,解决它:使用绑定源,将其DataSource属性设置为列表,然后将数据网格视图的数据源设置为此绑定源。现在,代码应如下所示:

 public partial class frmTestDataGridView : Form { BindingSource bindingSource1 = new BindingSource(); List datasource = new List(); public frmTestDataGridView() { InitializeComponent(); datasource.Add("item1"); datasource.Add("item2"); datasource.Add("item3"); bindingSource1.DataSource = datasource; dataGridView1.DataSource = bindingSource1; } private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e) { if (openFileDialog1.ShowDialog() == DialogResult.OK) { int row = e.RowIndex; int clmn = e.ColumnIndex; if (e.RowIndex == dataGridView1.Rows.Count - 1) { bindingSource1.Add(""); } dataGridView1.Rows[row].Cells[clmn].Value = openFileDialog1.FileName; } } } 

如果在使用来自Janus的DataGrid或GridEX(在我的情况下)中编辑行中的值时遇到此错误,请记住使用Row.BeginEdit()Row.EndEdit() )。 Darrel Lee在这里发布的示例代码( https://stackoverflow.com/a/9143590/1278771 )提醒我使用这些我忘记使用的说明,这解决了我的问题。