For the first time in a while, I can find no use information on this exception on Google... hoping someone else may have come across it.
I have a DataGridView that I validate for empty cells on the Leave event and remove those rows.
If I leave the last cell empty in the last row and tab away from the DGV the following exception is thrown:
System.InvalidOperationException: Cell is not in a DataGridView. The
cell cannot retrieve the inherited cell style.
I am not using Data Binding and a if I place a Breakpoint at this.dataGridView1.Rows.RemoveAt(c.RowIndex);
It is hit and if if I step into this line the exception is thrown during the execution of non-user code...
I had thought this was to do with Uncommitted Changed but it seems explicitly committing the changes does not affect the outcome.
My Leave
Event code:
private void dataGridView1_Leave(object sender, EventArgs e)
{
if (this.dataGridView1.IsCurrentRowDirty || this.dataGridView1.IsCurrentCellDirty) this.dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit);
//Validate for empty rows
foreach(DataGridViewRow row in this.dataGridView1.Rows)
{
foreach(DataGridViewCell c in row.Cells)
{
if(c.Value == null || c.Value.ToString() == String.Empty)
{
if (c.EditedFormattedValue == null || c.EditedFormattedValue.ToString() == "")
{
this.dataGridView1.Rows.RemoveAt(c.RowIndex);
break;
}
}
}
}
}
Exception Data is here:
System.InvalidOperationException: Cell is not in a DataGridView. The cell cannot retrieve the inherited cell style.
at System.Windows.Forms.DataGridViewCell.GetInheritedStyle(DataGridViewCellStyle inheritedCellStyle, Int32 rowIndex, Boolean includeColors)
at System.Windows.Forms.DataGridView.OnCellValidating(DataGridViewCell& dataGridViewCell, Int32 columnIndex, Int32 rowIndex, DataGridViewDataErrorContexts context)
at System.Windows.Forms.DataGridView.CommitEdit(DataGridViewCell& dataGridViewCurrentCell, DataGridViewDataErrorContexts context, DataGridViewValidateCellInternal validateCell, Boolean fireCellLeave, Boolean fireCellEnter, Boolean fireRowLeave, Boolean fireRowEnter, Boolean fireLeave)
at System.Windows.Forms.DataGridView.EndEdit(DataGridViewDataErrorContexts context, DataGridViewValidateCellInternal validateCell, Boolean fireCellLeave, Boolean fireCellEnter, Boolean fireRowLeave, Boolean fireRowEnter, Boolean fireLeave, Boolean keepFocus, Boolean resetCurrentCell, Boolean resetAnchorCell)
at System.Windows.Forms.DataGridView.ProcessDialogKey(Keys keyData)
at System.Windows.Forms.Control.ProcessDialogKey(Keys keyData)
at System.Windows.Forms.TextBoxBase.ProcessDialogKey(Keys keyData)
at System.Windows.Forms.Control.PreProcessMessage(Message& msg)
at System.Windows.Forms.Control.PreProcessControlMessageInternal(Control target, Message& msg)
at System.Windows.Forms.Application.ThreadContext.PreTranslateMessage(MSG& msg)
at System.Windows.Forms.Application.ThreadContext.System.Windows.Forms.UnsafeNativeMethods.IMsoComponent.FPreTranslateMessage(MSG& msg)
at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.Run(Form mainForm)
Answer
If you're using foreach-loop, you can't remove items from the collection it's using. Here you're removing items from this.dataGridView1.Rows.
Try this:
for (int i = 0; i < dataGridView1.Rows.Count; i++)
{
DataGridViewRow row = dataGridView1.Rows[i];
for (int k = 0; k < row.Cells.Count; k++)
{
DataGridViewCell c = row.Cells[k];
if (c.Value == null || c.Value.ToString() == String.Empty)
{
if (c.EditedFormattedValue == null || c.EditedFormattedValue.ToString() == "")
{
this.dataGridView1.Rows.RemoveAt(c.RowIndex);
// Decrease i, as the collection got smaller
i--;
break;
}
}
}
}
No comments:
Post a Comment