抛出Validation.Error事件的奇怪顺序 - 添加在Removed之前触发

时间:2012-05-17 02:57:50

标签: wpf wpf-4.0

就Validation.Error事件的触发顺序而言,我的行为很奇怪。根据文档here数据绑定引擎首先删除可能已添加到绑定元素的Validation.Errors附加属性的任何ValidationError 。因此,应该在添加之前触发已移除的ValidationErrorEvent,但奇怪的是,在我的情况下已添加事件在之前被触发已移除事件。这是我正在使用的代码。

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>

代码隐藏

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);
    }
}

有没有人遇到过这个问题,或者我的代码中有什么问题?

4 个答案:

答案 0 :(得分:1)

查看source code,在删除旧验证错误之前添加新验证错误的步骤

  

是经过精心安排的,以避免经历过#34;没有错误&#34;用另一个

替换一个错误时的状态

答案 1 :(得分:0)

记住fractor的答案你可以尝试做一些解决方法。 创建一个计数器,表示已验证控件的错误数:

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);
    }
}

我知道这是一个古老的问题,但我希望它会有所帮助。

答案 2 :(得分:0)

我阅读了很多论坛,发现它的MS 3.5到4.0升级问题,并且没有直接解决方案。 https://social.msdn.microsoft.com/Forums/vstudio/en-US/590dc1d4-045e-4bdf-a84b-d759a5903633/validationerror-giving-strange-behavior

但是您可以使用下面的代码来做出决定

(((BindingExpressionBase)e.Error?.BindingInError).HasValidationError

true =如果有验证错误,否则为false。 它对我有用。

答案 3 :(得分:-1)

您可以使用此事件来确定错误状态的更改,但由于它们出现故障(有充分理由,请参阅fractor的回答),您应该改为阅读Validation.HasErrors属性。

var hasErrors = (bool)GetValue(Validation.HasErrorProperty);

在同一个处理程序中执行此操作,它始终是正确的。