|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Prevent DataRow DeletionScenario: 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 You could ask confirmation in your UI code before performing the actual
deletion ? What is the control that triggers this ? A button ? -- Patrice "AxelHecker" <AxelHec***@discussions.microsoft.com> a écrit dans le message de news: 15162EEC-4C2B-419E-A6C5-D3E4ED453***@microsoft.com...Show quote > 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 > Hi Patrice. As I said in my example, the control that triggers this is the
"Delete"-button in a BindingNavigator. Actually, this button does have a Click event, but unfortunately, this event only fires when the RowDelete has already completed (both RowDeleting and RowDeleted events of the DataRow come before the Click event of the Delete-button of the BindingNavigator). Consequently, to do anything in the Click event of the Delete-button is of no use. Thanks for your comment anyway. Axel. -- Show quoteAxel Hecker "Patrice" wrote: > You could ask confirmation in your UI code before performing the actual > deletion ? What is the control that triggers this ? A button ? > > -- > Patrice > > "AxelHecker" <AxelHec***@discussions.microsoft.com> a écrit dans le message > de news: 15162EEC-4C2B-419E-A6C5-D3E4ED453***@microsoft.com... > > 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 > > > > > Pratrice, after rethinking and a closer a look at the the properties of the
BindingNavigator, your question lead me to the solution: the automatic delete action of the Delete button of the BindingNavigator can be disabled by setting the DeleteItem property to nothing and then use the Click event of the Delete button (where I have full control on further actions). Sorry, things go crazy ways. Thanks again, your question helped me a lot. -- Show quoteAxel Hecker "AxelHecker" wrote: > Hi Patrice. As I said in my example, the control that triggers this is the > "Delete"-button in a BindingNavigator. Actually, this button does have a > Click event, but unfortunately, this event only fires when the RowDelete has > already completed (both RowDeleting and RowDeleted events of the DataRow come > before the Click event of the Delete-button of the BindingNavigator). > Consequently, to do anything in the Click event of the Delete-button is of no > use. > > Thanks for your comment anyway. Axel. > > > -- > Axel Hecker > > > > "Patrice" wrote: > > > You could ask confirmation in your UI code before performing the actual > > deletion ? What is the control that triggers this ? A button ? > > > > -- > > Patrice > > > > "AxelHecker" <AxelHec***@discussions.microsoft.com> a écrit dans le message > > de news: 15162EEC-4C2B-419E-A6C5-D3E4ED453***@microsoft.com... > > > 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 > > > > > > > > > |
|||||||||||||||||||||||