1

I have been stuck with this for hours and hope somebody can shed some light on this. Say I have a DataGrid control:

<DataGrid ItemsSource="{Binding Path=RealEstates, ValidatesOnExceptions=True}"
          AutoGenerateColumns="True"
          Name="grdData_RealEstate" 
          Margin="5,5,5,5"
          Style="{StaticResource DataGridStyle}"
          RowStyle="{StaticResource DataGridRowStyle}">
</DataGrid>

Which is bound to a propetry that exposes the RealEstates table of a DataSet.

Now when the user deletes a row from this table I would like to perform some checks before allowing or denying the delete. What I have done is to subscribe to the RowDeleting event of the DataTable.

workingDataSet.Tables["realestates"].RowDeleting += Database_RowDeleting;

Then in the method that handles it, I just throw an exception. The actual logic will follow once I get this working.

void Database_RowDeleting(object sender, DataRowChangeEventArgs e)
{
    throw (new Exception("Can't delete"));            
}

This works and raises the exception when I am trying to delete any row from the DataGrid. The problem though is that the DataGrid control is not catching the exception (red border the DataGrid control) which causes my program to shut down and is obviously not what I want. Any idea what I am doing wrong here? How can I get the DataGrid to catch these exceptions?

Avalan
  • 159
  • 1
  • 10
  • 1
    The simple answer is you can't easily catch it. For that reason throwing Exceptions from event handlers in C# is generally not a good idea. Instead simply feed the result of the delete into a custom EventArgs class, or raise DeleteSucceeded / DeleteFailed events as required. – Octopoid May 26 '15 at 21:10
  • @Octopoid: Not exactly sure what you meant with you proposed solution but you placed me on the right track with your statement to avoid throwing exceptions inside event handlers. I think I have a solution now, will test it and place it as the answer if it works. Thanks! – Avalan May 27 '15 at 08:09

1 Answers1

0

Okay I have a solution for anybody else interested.

I subscribed to both the RowDeleting and RowDeleted events of the DataTable:

workingDataSet.Tables["realestates"].RowDeleting += Database_RowDeleting;
workingDataSet.Tables["realestates"].RowDeleted += Database_RowDeleted;

Then I created a field to allow or deny the delete:

bool allowRowDelete;

Next I perform my validation logic inside the RowDeleting method:

void Database_RowDeleting(object sender, DataRowChangeEventArgs e)
{
    allowRowDelete = true;

    if (Convert.ToUInt32(e.Row["id"]) > 3)
        allowRowDelete = false;
}

Then in the RowDeleted method I reject the delete if the validation failed:

void Database_RowDeleted(object sender, DataRowChangeEventArgs e)
{            
    if (!allowRowDelete)
        e.Row.RejectChanges();
}

Although this is an answer to this question it's not my preffered solution since I originally wanted to use Foreign Key Constraints as in one of my other posts this will have to do for now.

Some other post, that people with this same problem might find interesting:

http://www.pcreview.co.uk/threads/how-to-stop-a-change-in-the-rowdeleting-event-handler.1239208/

What is the "pressed the delete key" event for the WPF Datagrid?

http://www.experts-exchange.com/Programming/Languages/C_Sharp/Q_21758199.html

http://wpf.codeplex.com/discussions/39077

Community
  • 1
  • 1
Avalan
  • 159
  • 1
  • 10
  • Inside your `RowDeleting` event handler you should just be able to set `e.Cancel = true;` to cancel the delete from continuing. – Octopoid May 27 '15 at 09:57
  • Now that would have made much more sense, but turns out `DataRowChangeEventArgs` does not have such a member. It only provides the 'Action' which was taken (obviously delete) and the row upon which this action was performed. – Avalan May 27 '15 at 10:15
  • My mistake - wrong sort of data grid row! As you say, `e.Cancel` would have been nice and neat, but your solution is absolutely fine anyway. – Octopoid May 27 '15 at 10:19