问题
I am getting strange behavior as far as order of firing of Validation.Error event is concerned. According to the documentation here, the data binding engine first removes any ValidationError that may have been added to the Validation.Errors attached property of the bound element. Accordingly, the ValidationErrorEvent for Removed should be fired prior to the Added, but strangely in my case the Added event gets fired before the Removed event. Here is the code that I am using.
XAML
<TextBox Grid.Row="3" Grid.Column="1" Name="txtGroupsPerRow" >
<TextBox.Text>
<Binding Path="StandardRack.NoOfGroupsPerRow" ValidatesOnDataErrors="True" NotifyOnValidationError="True"
UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<gs:NumericValidationRule PropertyName="No Of Groups Per Row"/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
CodeBehind
private RoutedEventHandler _errorEventRoutedEventHandler;
private void UserControl_Loaded(object sender, RoutedEventArgs e) {
_errorEventRoutedEventHandler = new RoutedEventHandler(ExceptionValidationErrorHandler);
this.AddHandler(System.Windows.Controls.Validation.ErrorEvent, _errorEventRoutedEventHandler, true);
}
private void UserControl_Unloaded(object sender, RoutedEventArgs e) {
this.RemoveHandler(System.Windows.Controls.Validation.ErrorEvent, _errorEventRoutedEventHandler);
_errorEventRoutedEventHandler = null;
}
//Added fired before Removed
private void ExceptionValidationErrorHandler(object sender, RoutedEventArgs e) {
if (validationErrorEvent.Action == ValidationErrorEventAction.Added) {
viewModel.AddValidationError(propertyPath, validationErrorEvent.Error.ErrorContent.ToString());
}
else if (validationErrorEvent.Action == ValidationErrorEventAction.Removed) {
viewModel.RemoveValidationError(propertyPath);
}
}
Has anyone come across this issue, or is there something wrong in my code?
回答1:
Looking at the source code, the steps of adding a new validation error before removing an old one
are carefully ordered to avoid going through a "no error" state while replacing one error with another
回答2:
Keeping in mind fractor's answer you can try to do a little workaround. Create some counter that will represent errors count of validated control:
int errorCounter = 0;
private void TextBox_Error(object sender, ValidationErrorEventArgs e)
{
var tb = sender as TextBox;
if (tb != null)
{
errorCounter += (e.Action == ValidationErrorEventAction.Added) ? 1 : -1;
//here do whatever you want to with you stored information about error
someControl.IsEnabled = !(errorCounter > 0);
}
}
I know it's kinda old question but I hope it will help.
回答3:
You can use this event to determine a change in error state, but since they appear out of order (for good reason, see fractor's answer), you should read the Validation.HasErrors property instead.
var hasErrors = (bool)GetValue(Validation.HasErrorProperty);
Do this in the same handler, it will always be correct.
来源:https://stackoverflow.com/questions/10629278/strange-order-of-firing-of-validation-error-event-added-fired-before-removed