LenTompkins
asked on
InvalidOperationException Occurs When Editing the Last Row After Previously Deleting the last Row from a DataGrid
I am having a problem when I delete the last row of a table. The delete will work properly, but if I then edit the new last row I am getting an Invalid Operation Exception from my CurrentChanged Event Handler. What I noticed is that when I am deleting the last record, it does the delete to the datagrid then jumps to the CurrentChanged event handler and after it finishes, it goes back and finishes the rest of the delete routine. Why is it doing this? Any thoughts?
// Instantiate binding source for binding navigator
this.m_srcCollectionHistor yType = new BindingSource();
this.m_srcCollectionHistor yType.Data Source = this.m_dsCollectionHistory .Collectio nHistoryTy pe;
this.grdCollectionHistoryT ype.AutoGe nerateColu mns = false;
this.grdCollectionHistoryT ype.DataSo urce = this.m_srcCollectionHistor yType;
this.navCollectionHistoryT ype.Bindin gSource = this.m_srcCollectionHistor yType;
this.m_srcCollectionHistor yType.Curr entChanged += new EventHandler(m_srcCollecti onHistoryT ype_Curren tChanged);
//Event Handlers
private void btnDeleteCollectionHistory Type_Click (object sender, EventArgs e)
{
DataRowView rowView =
(DataRowView)this.grdColle ctionHisto ryType.Cur rentRow.Da taBoundIte m;
try
{
string currentRow = rowView["Type"].ToString() ;
if (currentRow == "Unknown")
{
MessageBox.Show("You cannot delete an 'Unknown'");
return;
}
rowView.Delete(); <-- Jumps to CurrentChanged event handler after executing this statement
int recordsAffected =
this.m_adpCollectionHistor yType.Upda te(rowView .Row);
MessageBox.Show(string.For mat("Colle ction History Type: '{0}' deleted.", currentRow));
}
catch (InvalidConstraintExceptio n)
{
MessageBox.Show("You cannot delete a record that is linked to records in Collection History Key Table!");
}
catch (SqlException)
{
MessageBox.Show("You cannot delete this record!");
}
}
private void m_srcCollectionHistoryType _CurrentCh anged(obje ct sender, EventArgs e)
{
if (this.grdCollectionHistory Type.Curre ntRow == null) return;
if (this.grdCollectionHistory Type.Curre ntRow.Inde x == (this.grdCollectionHistory Type.RowCo unt - 1))
{
this.grdCollectionHistoryT ype.DataSo urce = null; <---- Causes InvalidOperationException occurs here
this.grdCollectionHistoryT ype.DataSo urce = m_srcCollectionHistoryType ;
}
// Instantiate binding source for binding navigator
this.m_srcCollectionHistor
this.m_srcCollectionHistor
this.grdCollectionHistoryT
this.grdCollectionHistoryT
this.navCollectionHistoryT
this.m_srcCollectionHistor
//Event Handlers
private void btnDeleteCollectionHistory
{
DataRowView rowView =
(DataRowView)this.grdColle
try
{
string currentRow = rowView["Type"].ToString()
if (currentRow == "Unknown")
{
MessageBox.Show("You cannot delete an 'Unknown'");
return;
}
rowView.Delete(); <-- Jumps to CurrentChanged event handler after executing this statement
int recordsAffected =
this.m_adpCollectionHistor
MessageBox.Show(string.For
}
catch (InvalidConstraintExceptio
{
MessageBox.Show("You cannot delete a record that is linked to records in Collection History Key Table!");
}
catch (SqlException)
{
MessageBox.Show("You cannot delete this record!");
}
}
private void m_srcCollectionHistoryType
{
if (this.grdCollectionHistory
if (this.grdCollectionHistory
{
this.grdCollectionHistoryT
this.grdCollectionHistoryT
}
ASKER
I am new to coding in C# but how do I commit the change to the binding source? I thought that when you update the table adapter, the binding source gets updated as well.
Using:
Bindingsource.EndEdit() (Replace Bindingsource with the actual name of your bindingsource)
When the EndEdit method is called, all pending changes are applied to the underlying data source.
Bindingsource.EndEdit() (Replace Bindingsource with the actual name of your bindingsource)
When the EndEdit method is called, all pending changes are applied to the underlying data source.
ASKER
I just tried that and the delete works, but when I then edit the last row of the table I am getting an "Operation is not valid because it results in a re-entrant call to the set current cell address core function. It is occrring in:
if (this.grdCollectionHistory Type.Curre ntRow.Inde x == (this.grdCollectionHistory Type.RowCo unt - 1))
{
this.grdCollectionHistoryT ype.DataSo urce = null;
this.grdCollectionHistoryT ype.DataSo urce = m_srcCollectionHistoryType ;
}
I added the following code so that when I added a new record to the end of the table and then deleted it, the code was abending. I thought this would resolve it, but now after I have added a new record, then deleted it, and then edited the last row, I get this error.
I would move this to the delete routine, but after I do:
rowView.Delete(); it jumps to the CurrentChanged method.
Am I going about this all wrong?
if (this.grdCollectionHistory
{
this.grdCollectionHistoryT
this.grdCollectionHistoryT
}
I added the following code so that when I added a new record to the end of the table and then deleted it, the code was abending. I thought this would resolve it, but now after I have added a new record, then deleted it, and then edited the last row, I get this error.
I would move this to the delete routine, but after I do:
rowView.Delete(); it jumps to the CurrentChanged method.
Am I going about this all wrong?
What are you trying to accomplish with that code?
ASKER
I added the code to bypass an error that I was getting after deleting the last row of the table. I just commented out that code, and added a new record then deleted it. After it does the delete statement, it jumps to the Current Changed method and abends with System Index out of range exception. Everytime I come into this current changed, should I perform an end-Edit so that the binding source is in sync?
Are you saying it abends in the currentchanged even if there is no code there?
Remove the code and let's figure out the problem.
That code was just because of the error correct? You don't actually need to do anything?
Remove the code and let's figure out the problem.
That code was just because of the error correct? You don't actually need to do anything?
ASKER
Here is the routine the way I now have it:
private void m_srcCollectionHistoryType _CurrentCh anged(obje ct sender, EventArgs e)
{
if (this.grdCollectionHistory Type.Curre ntRow == null) return;
if (this.grdCollectionHistory Type.Curre ntRow.Inde x == (this.grdCollectionHistory Type.RowCo unt - 1))
{
// this.m_srcCollectionHistor yType.EndE dit();
// this.grdCollectionHistoryT ype.DataSo urce = null;
// this.grdCollectionHistoryT ype.DataSo urce = m_srcCollectionHistoryType ;
}
//Save original 'Type' column in case it needs to be restored
int rowIndex = this.grdCollectionHistoryT ype.Curren tRow.Index ;
DataRow row = this.m_dsCollectionHistory .Collectio nHistoryTy pe.Rows[ro wIndex];
string origType = row["Type", DataRowVersion.Original].T oString();
//this.grdCollectionHistor yType.EndE dit();
try
{
DataRowView drv = (DataRowView)this.grdColle ctionHisto ryType.Cur rentRow.Da taBoundIte m;
if (drv.Row.RowState == DataRowState.Modified)
{
if (origType == "Unknown")
{
MessageBox.Show("You cannot modify an 'Unknown'");
// Change Type back to "Unknown"
this.m_dsCollectionHistory .Collectio nHistoryTy pe[rowInde x].Type = origType;
return;
}
//Update "Last Touched By" & "Last Touched Date" columns before saving updated record
this.m_dsCollectionHistory .Collectio nHistoryTy pe[rowInde x].LastTou chedBy =
SystemInformation.UserName ;
this.m_dsCollectionHistory .Collectio nHistoryTy pe[rowInde x].LastTou chedDate = DateTime.Now;
int recordsAffected =
this.m_adpCollectionHistor yType.Upda te(drv.Row );
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message );
}
When I delete the last row, after the delete, it goes right to this current changed and I am getting an error on:
DataRowView drv = (DataRowView)this.grdColle ctionHisto ryType.Cur rentRow.Da taBoundIte m;
saying the row index is out of bounds.
How should I resolve this?
private void m_srcCollectionHistoryType
{
if (this.grdCollectionHistory
if (this.grdCollectionHistory
{
// this.m_srcCollectionHistor
// this.grdCollectionHistoryT
// this.grdCollectionHistoryT
}
//Save original 'Type' column in case it needs to be restored
int rowIndex = this.grdCollectionHistoryT
DataRow row = this.m_dsCollectionHistory
string origType = row["Type", DataRowVersion.Original].T
//this.grdCollectionHistor
try
{
DataRowView drv = (DataRowView)this.grdColle
if (drv.Row.RowState == DataRowState.Modified)
{
if (origType == "Unknown")
{
MessageBox.Show("You cannot modify an 'Unknown'");
// Change Type back to "Unknown"
this.m_dsCollectionHistory
return;
}
//Update "Last Touched By" & "Last Touched Date" columns before saving updated record
this.m_dsCollectionHistory
SystemInformation.UserName
this.m_dsCollectionHistory
int recordsAffected =
this.m_adpCollectionHistor
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message
}
When I delete the last row, after the delete, it goes right to this current changed and I am getting an error on:
DataRowView drv = (DataRowView)this.grdColle
saying the row index is out of bounds.
How should I resolve this?
I don't fully understand what you are doing and why you are doing it in this event but to solve your issue I would try not using CurrentRow since that is the problem. Your CurrentRow is not pointing at the right place.
Doesn't your e arg give you the rowindex. Use that instead?
Something like:
DataRowView drv = (DataRowView)this.grdColle ctionHisto ryType.e(R owIndex).D ataBoundIt em;
Doesn't your e arg give you the rowindex. Use that instead?
Something like:
DataRowView drv = (DataRowView)this.grdColle
ASKER
The dataRow View statement doesn't work here. It says that Systems.Form.datagrid doesn't contain a definition for e.
I have this routine, because, when I want to change a row's text we have one row that can never be changed. I was defining a row view to see if the original text =" UnKnown". If it is, the change will be cancelled, otherwise it continues on. where else can I perform this test?
I have this routine, because, when I want to change a row's text we have one row that can never be changed. I was defining a row view to see if the original text =" UnKnown". If it is, the change will be cancelled, otherwise it continues on. where else can I perform this test?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
No I don't but I will try that now. Thank you for all of your assistance. I'll try it now and get back to you.
ASKER
Yes, Thank you very much. I finally solved the problem by getting rid of CurrentChanged performing a Row Validation. Then I asked if the field was equal to the string Unknown and if it was, I then created the data row view to determine if the row state was modified. It now works.
I and some other new programmers have been working on this problem for over 1 week.
I and some other new programmers have been working on this problem for over 1 week.
Nicely done. Glad I could help.
It may be that you deleted the last row but didn't commit the change to the bindingsource yet?
So currentrow and bindingsource row are out of synch one doesnt exist and the other one still does?
You could try either changing your code to use the bindingsource for what you are doing or commiting the changes righ before by using bindingsource.endedit at the beginning of your event?