G
Guest
Hi!
Scenario: A User deletes a row in a DataTable; a MessageBox comes up and
asks if he/she really wants to delete the row; in case the answer is "no",
the row deletion should be cancelled.
There are straightforward solutions for this scenario when an intelligent
control like the DataGridView is used, because such control exhibits a
"UserDeletingRow" event that provides a CANCEL property to be set to TRUE.
But in case no such control is used, I cannot see a clear solution. I have
searched the newsgroups for this, and I find two proposals:
1) Use the RowDeleted event of the DataRow by calling
DataRow.RejectChanges(). I admit this to be a feasible solution, but it has
nasty side effects, like:
- the row will first be deleted and only then be "un-deleted" - including
possible child rows (possibly several generations of them), that also have to
be un-deleted
- after the delete, a lot of other actions occur, like position changes,
for example, that also have to be undone
I conclude that using RowDeleted is not a good a solution (and I guess that
the architects of the DataGridView would agree, because they provided
something better).
2) Use the RowDeleting event of the DataRow.
This looks better, because the RowDeleting event is called before the row is
actually deleted. But - helas - this event doesn't have a CANCEL property.
In the newsgroups I found a solution based on this idea by David Sceppa
(whom I truely admire), which goes like this (I cite):
*******David Sceppa speaking******
You could trap for the RowDeleting event and call the
DataRow's RejectChanges method if you do not want to allow the
deletion. You could also throw an exception if that's
appropriate in your application.
Here's some sample code I used to accomplish this task:
DataTable tbl = new DataTable();
tbl.Columns.Add("CustomerID");
tbl.Columns.Add("CompanyName");
tbl.LoadDataRow(new object[] {"Comp1", "Company #1"}, true);
tbl.RowDeleting += new DataRowChangeEventHandler(DeleteHandler);
Console.WriteLine(tbl.Rows.Count);
try
{
tbl.Rows[0].Delete();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.WriteLine(tbl.Rows.Count);
static void DeleteHandler(object sender, DataRowChangeEventArgs
e)
{
e.Row.RejectChanges();
throw new Exception("Deletion disallowed");
}
I hope this information proves helpful.
*******End of Citation *******
The point here seems to be to throw the exception. As far as I can see,
RejectChanges() doesn't do anything, because at this point in time, the row
to be deleted still has a RowState of "Unchanged" (this is what my debugger
tells me), and you cannot reject a change that has not yet taken place.
In David's example, to throw an exception does the job, because the row is
deleted *programmatically*, and hence, there is a point where the exception
thrown can be caught. But what can I do when the row is deleted by a user
action, like, pressing the Delete button on a BindingNavigator? I have no
idea where I could catch the exception thrown.
Does anybody have an idea? Thanks for any hints.
Axel Hecker
Scenario: A User deletes a row in a DataTable; a MessageBox comes up and
asks if he/she really wants to delete the row; in case the answer is "no",
the row deletion should be cancelled.
There are straightforward solutions for this scenario when an intelligent
control like the DataGridView is used, because such control exhibits a
"UserDeletingRow" event that provides a CANCEL property to be set to TRUE.
But in case no such control is used, I cannot see a clear solution. I have
searched the newsgroups for this, and I find two proposals:
1) Use the RowDeleted event of the DataRow by calling
DataRow.RejectChanges(). I admit this to be a feasible solution, but it has
nasty side effects, like:
- the row will first be deleted and only then be "un-deleted" - including
possible child rows (possibly several generations of them), that also have to
be un-deleted
- after the delete, a lot of other actions occur, like position changes,
for example, that also have to be undone
I conclude that using RowDeleted is not a good a solution (and I guess that
the architects of the DataGridView would agree, because they provided
something better).
2) Use the RowDeleting event of the DataRow.
This looks better, because the RowDeleting event is called before the row is
actually deleted. But - helas - this event doesn't have a CANCEL property.
In the newsgroups I found a solution based on this idea by David Sceppa
(whom I truely admire), which goes like this (I cite):
*******David Sceppa speaking******
You could trap for the RowDeleting event and call the
DataRow's RejectChanges method if you do not want to allow the
deletion. You could also throw an exception if that's
appropriate in your application.
Here's some sample code I used to accomplish this task:
DataTable tbl = new DataTable();
tbl.Columns.Add("CustomerID");
tbl.Columns.Add("CompanyName");
tbl.LoadDataRow(new object[] {"Comp1", "Company #1"}, true);
tbl.RowDeleting += new DataRowChangeEventHandler(DeleteHandler);
Console.WriteLine(tbl.Rows.Count);
try
{
tbl.Rows[0].Delete();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.WriteLine(tbl.Rows.Count);
static void DeleteHandler(object sender, DataRowChangeEventArgs
e)
{
e.Row.RejectChanges();
throw new Exception("Deletion disallowed");
}
I hope this information proves helpful.
*******End of Citation *******
The point here seems to be to throw the exception. As far as I can see,
RejectChanges() doesn't do anything, because at this point in time, the row
to be deleted still has a RowState of "Unchanged" (this is what my debugger
tells me), and you cannot reject a change that has not yet taken place.
In David's example, to throw an exception does the job, because the row is
deleted *programmatically*, and hence, there is a point where the exception
thrown can be caught. But what can I do when the row is deleted by a user
action, like, pressing the Delete button on a BindingNavigator? I have no
idea where I could catch the exception thrown.
Does anybody have an idea? Thanks for any hints.
Axel Hecker