I am trying to implement row-level validation when using the RadGridView bound to a DataView. The xaml looks like this:
The TableDataView property is a DataView from a DataSet into which I have read a series of records, e.g.,
TableDataView = myDataSet.Tables[0].DefaultView;
I subscribe to the following events:
myDataSet.Tables[0].RowChanging += new DataRowChangeEventHandler(DataTable_RowChanging);
myDataSet.Tables[0].RowChanged += new DataRowChangeEventHandler(DataTable_RowChanged);
I am using row-level validation because the row change may be rejected by the DBMS when I go to update the backing store. With other grids, the validation can be done before the focus leaves the current row and signaling a validation failure prevents the user from leaving that row without either correcting the error or rolling the change back. I am trying to use the e.Row.RowError property that I recieve in the DataRowChangeEventArgs e argument passed to my event handlers. That does not seem to have the effect that I am looking for: specifically, the row header should show an error and the user is restricted from leaving the record until the issue is addressed.
Any suggestions on how this would be handled from my view-model/model? Maybe the change in error status needs to be propagated back to the grid in some fashion other than this because this has no effect. If I work through cell-level validation, I get results that one would expect. But, cell-level validation is not useful in this condition.
Edit: By the way, if you try to use e.Row.RejectChanges() in the DataTable_RowChanging event handler, you'll get an error that says that you should throw an exception to cancel the row operation. If I throw an InvalidOperationException, for example, it is caught by my unhandled exception handler. I think that is the Microsoft method - the exception will be caught by the grid control and the message displayed. So, no joy in that direction, either.
Edit 2: Ok, so we don't handle it from our (view-)model, we go out to the code behind. Change the xaml to include RowValidating="OnRowValidating" and RowValidated="OnRowValidated" and add those handlers. In a stub OnRowValidating
handler, write:
Now we get the expected behavior: it will flag the record in the header and the tool tip 'byte me!' is shown on mouse over. This brings up another problem - the cancel behavior. As expected, the first escape cancels the edit on the current cell (really the last cell with the focus before the validation event). The second escape reverts the record. Almost. Here's what happens: if the first cell contained the value '5' and it was changed to '55' before the commit, the '55' is left in that field after the cancel. So the user now sees his incorrect value(s) in the grid after he performed the escape sequence.
The frustration with this behavior is quite high. We're so close in getting the correct behavior from the view-model. Why didn't Telerik just allow the exception ala MS to signal the validation error? And, when I use what appears to be the Telerik method, it fails in the rollback. I am using the last Q2 release because my attempt to move to the Q3 found a lack of fixes for what I currently have in the Q2 code and new errors introduced in the Q3 release.
<
telerik:RadGridView
Grid.Column
=
"1"
Grid.Row
=
"1"
Name
=
"_gridTableGrid"
ItemsSource
=
"{Binding TableDataView, Mode=TwoWay}"
/>
The TableDataView property is a DataView from a DataSet into which I have read a series of records, e.g.,
TableDataView = myDataSet.Tables[0].DefaultView;
I subscribe to the following events:
myDataSet.Tables[0].RowChanging += new DataRowChangeEventHandler(DataTable_RowChanging);
myDataSet.Tables[0].RowChanged += new DataRowChangeEventHandler(DataTable_RowChanged);
Any suggestions on how this would be handled from my view-model/model? Maybe the change in error status needs to be propagated back to the grid in some fashion other than this because this has no effect. If I work through cell-level validation, I get results that one would expect. But, cell-level validation is not useful in this condition.
Edit: By the way, if you try to use e.Row.RejectChanges() in the DataTable_RowChanging event handler, you'll get an error that says that you should throw an exception to cancel the row operation. If I throw an InvalidOperationException, for example, it is caught by my unhandled exception handler. I think that is the Microsoft method - the exception will be caught by the grid control and the message displayed. So, no joy in that direction, either.
Edit 2: Ok, so we don't handle it from our (view-)model, we go out to the code behind. Change the xaml to include RowValidating="OnRowValidating" and RowValidated="OnRowValidated" and add those handlers. In a stub OnRowValidating
handler, write:
private
void
OnRowValidating(
object
sender, Telerik.Windows.Controls.GridViewRowValidatingEventArgs e)
{
e.IsValid =
false
;
e.ValidationResults.Add(
new
Telerik.Windows.Controls.GridViewCellValidationResult() {ErrorMessage =
"byte me!"
} );
}
Now we get the expected behavior: it will flag the record in the header and the tool tip 'byte me!' is shown on mouse over. This brings up another problem - the cancel behavior. As expected, the first escape cancels the edit on the current cell (really the last cell with the focus before the validation event). The second escape reverts the record. Almost. Here's what happens: if the first cell contained the value '5' and it was changed to '55' before the commit, the '55' is left in that field after the cancel. So the user now sees his incorrect value(s) in the grid after he performed the escape sequence.
The frustration with this behavior is quite high. We're so close in getting the correct behavior from the view-model. Why didn't Telerik just allow the exception ala MS to signal the validation error? And, when I use what appears to be the Telerik method, it fails in the rollback. I am using the last Q2 release because my attempt to move to the Q3 found a lack of fixes for what I currently have in the Q2 code and new errors introduced in the Q3 release.