I searched a lot for this error many same question is already asked, but its not solving my problem. I am getting
Operation is not valid because it results in a reentrant call to the SetCurrentCellAddressCore function.
The scenario is I have datagridview
with TextboxColumn
I am using CellBeginEdit
to convert it in ComboBoxColumn
, and after CellValidate
I again change ComboBoxColumn to TextboxColumn. The codes works for all. but getting said error in exact line e.RowIndex = 2
throws this exception, but others rows doses not show error. if I omit this error and continue then e.RowIndex = 2 cell value comes blank, and other rows value work.
Here is the code of CellBeginEdit
if (e.ColumnIndex == 2 && e.RowIndex >= 0)
{
try
{
string s = Convert.ToString(_dgvCoarseAggegateTest[e.ColumnIndex, e.RowIndex].Value);
string s1 = Convert.ToString(_dgvCoarseAggegateTest[e.ColumnIndex, 0].Value);
DataGridViewComboBoxCell c = new DataGridViewComboBoxCell();
string _SizeName = _cGetParrent._mGetParentCellValue(ref _dgvCoarseAggegateTest, e.RowIndex, 1);
_mFillSieveSizeGridCombo(_mGetMetalSizeID(_SizeName), ref c); // Here My Combo Will GetValues from SQL and it Returning Value
_dgvCoarseAggegateTest[e.ColumnIndex, e.RowIndex] = c; // Heres the error When e.RowIndex == 2 and if e.RowIndex != 2 then no error
_dgvCoarseAggegateTest[e.ColumnIndex, e.RowIndex].Value = s;
_dgvCoarseAggegateTest[e.ColumnIndex, 0].Value = s1;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
How to resolve this.
UPDATE : No rows there user will add new row and select values, the base thing is i want to show combo and fill values from database, the fill values is depends on condition, so every time new values will come,
Sample Data
testTable
1 A
2 B
3 C
4 D
5 E
6 F
7 G
8 H
9 I
In column1 I added one combo with values from 1 to 9, in _mFillSieveSizeGridCombo
I am passing id to sql server 2008 and filling combo using Combo.Item.Add(x)
method.
There is a flag inside SetCurrentCellAddressCore()
preventing any re-entrant call corrupting internal values of DataGridView
. Usaully an event was raised with the flag = true and reset at the end of event.
To workaround this, you can simply add a wrapper of BeginInvoke()
inside the event, to get your process run after the event with async.
EDIT
The issue can be reproduce in EditOnEnter
mode, and the setter of cell outside the event in BeginInvoke
results the indefinite loop
private bool _suppressCellBeginEdit = false;
private void dgv_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)
{
var dgv = sender as DataGridView;
if (_suppressCellBeginEdit)
return;
if (e.ColumnIndex == 2 && e.RowIndex >= 0)
{
string s = Convert.ToString(dgv[e.ColumnIndex, e.RowIndex].Value);
string s1 = Convert.ToString(dgv[e.ColumnIndex, 0].Value);
DataGridViewComboBoxCell c = new DataGridViewComboBoxCell();
c.Items.Add(string.Format("x{0}:y{1} {2}", e.RowIndex, e.ColumnIndex, 0));
c.Items.Add(string.Format("x{0}:y{1} {2}", e.RowIndex, e.ColumnIndex, 1));
c.Items.Add(string.Format("x{0}:y{1} {2}", e.RowIndex, e.ColumnIndex, 2));
// special handling
if (e.RowIndex == e.ColumnIndex)
{
this.BeginInvoke(new Action(() =>
{
_suppressCellBeginEdit = true;
this.Invoke(new Action(() =>
{
c.Value = s;
dgv[e.ColumnIndex, e.RowIndex] = c;
dgv[e.ColumnIndex, 0].Value = s1;
}));
_suppressCellBeginEdit = false;
}));
}
else
{
c.Value = s;
dgv[e.ColumnIndex, e.RowIndex] = c;
dgv[e.ColumnIndex, 0].Value = s1;
}
}
}