如何确定在Validation.ErrorEvent中没有错误?

3

我有一个非常简单的检查,用于检测窗口中是否存在验证错误(假设所有绑定都设置了NotifyOnValidationError):

public MainWindow()
{
    InitializeComponent();
    DataContext = new VM();
    AddHandler(Validation.ErrorEvent, new RoutedEventHandler((s, e) =>
    {
        var args = (ValidationErrorEventArgs)e;
        var binding = (BindingExpression)args.Error.BindingInError;
        Title = binding.HasError ? $"Error {args.Error.ErrorContent}" : "";
    }), true);
}

当出现/消失错误时,事件被触发,但由于某些原因,即使没有更多的错误,HasError 仍然是 true,并且ErrorContent 包含旧的错误文本。

我做错了什么?


以下是一个带有验证的简单MCVE,其中Test应该为0
绑定错误(输入0a或空字符串)被正确设置/重置。验证错误被正确设置(输入1时),但未被重置(输入0时)。为什么?
实现INotifyPropertyChange没有任何区别。

xaml:

<TextBox Text="{Binding Test, NotifyOnValidationError=True, UpdateSourceTrigger=PropertyChanged}" />

视图模型:
public class VM : INotifyDataErrorInfo
{
    public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;

    int _test;
    public int Test
    {
        get => _test;
        set
        {
            _test = value;
            _error = value == 0 ? null : "Must be 0";
            ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(nameof(Test)));
        }
    }

    string _error;
    public bool HasErrors => _error != null;

    public IEnumerable GetErrors(string propertyName)
    {
        if (_error != null)
            yield return _error;
    }

}

1
你尝试过阅读并执行 ValidationErrorEventArgs.Action 属性 吗? - Fildor
@Fildor,看起来是这样的,谢谢。你也可以把它作为一个答案。我的方法是错误的(msdn 可以有一个简单的例子),我一直在想是我的工作去确定是否需要添加或删除错误。 - Sinatr
我认为关键在于这一点:“还要注意,无论是目标到源还是源到目标的有效值传输都会清除Validation.Errors附加属性。”因此,在您的示例中处理程序中检查binding.HasError时,它尚未被清除。 - Fildor
1个回答

1
如果您在处理程序中设置了Title,我认为您需要考虑ValidationErrorEventArgs.Action属性:

获取一个指示错误是新错误还是已清除的现有错误的值。

我不确定百分之百,但我怀疑,在您检查HasError 属性时,它尚未被清除。(这种怀疑基于 MSDN中的“还要注意,任何一方向(从目标到源或从源到目标)的有效值传输都会清除Validation.Errors附加属性。”)

是的,我必须维护错误列表,在 args.Action == ValidationErrorEventAction.Added 时添加它们,在 Removed 上删除它们,只有当列表为空时才没有更多错误。 - Sinatr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接