如何在 Catel 中捕获仅查看验证错误?

How to trap view-only validation errors in Catel?

试图弄清楚如何捕获仅查看验证错误,例如在绑定到整数的文本框中输入非数字字符 属性。我希望 Catel DataWindow 的行为始终如一。

描述:

我有一个 Catel MVVM window(使用 DataWindow 和一个带有模型 属性 的视图模型实现)

模型属性是一个整数:

    public Foo { get { GetValue .......... } }

视图模型属性也是一个整数,绑定到模型:

    [ViewModelToModel(...)]
    public Foo { get { GetValue .......... } }

在视图中,有一个绑定到 Foo 的文本框。当用户在文本框中输入非整数值时,绑定过程中自然会出现错误,并且由于文本框已将ValidatesOnExceptions设置为true,因此Catel info中出现以下内容留言栏:

我必须解决的两个问题:

网络搜索提供了几个可能的解决方案:

  1. Bind to a view model property that's a string, and handle mapping/conversion between the view model and the model
  2. Build support in the MVVM framework to trap UI validation errors and communicate them to the view model

解决方案 #1 绝对是 "workaround" 解决方案,因为这意味着我在视图模型中需要这样的东西(请原谅伪代码...):

    [ViewToViewModel(...)]
    public int Foo { ...... }

    // Also a Catel property
    public string Foo_Raw { ...... }

    // Property changed handlers for both the above properties, keeping them in sync with one another when possible...

    protected override void ValidateBusinessRules(List<.......> validationResults)
    {
        if (this.Foo_Raw != this.Foo.ToString())
        {
            validationResults.AddError("Foo must be an integer.");
        }
    }

我对创建这种摇摇欲坠的结构的前景并不满意。

我更愿意使用#2 之类的方法,但我在 Catel 的文档中没有看到任何表明支持该方法的内容。我错过了一个简单的解决方案吗?

更新: 我刚刚了解了数字文本框的行为,这可能是解决我的特定问题的另一种方法,但我真的在寻找更通用的解决方案来捕获 binding/UI 视图模型验证错误。

问题是您尝试接收的异常尚未绑定(因为绑定它们会出错)。虚拟机无法意识到这个问题。由于这是一个视图相关的问题,您只能在视图中处理此错误。

一种解决方案可能是将 WarningAndErrorValidator 捕获的消息转发到视图模型。您可以在视图上定义自己的 WarningAndErrorValidator 并订阅 Validated 事件。然后你可以将它传递给你的虚拟机。如果您希望在您的应用程序中的所有控件之间共享,这将需要您为视图编写自定义基础 class。

Geert van Horrik 的回答不太正确(除非我遗漏了什么,Geert)。 WarningAndErrorValidator 仅捕获视图模型错误,而不捕获来自可视化树本身的错误或绑定错误。事实证明,这是 InfoBarMessageControl 在没有 WarningAndErrorValidator 帮助的情况下所做的事情。

我所做的是,在我的 DataWindow 子类中,我复制了 InfoBarMessageControl 中捕获和分析可视化树验证错误的逻辑,并且我维护了一个类似的错误消息数据结构。

然后我像这样覆盖 DataWindow::ValidateData

    protected override bool ValidateData()
    {
        // In addition to base class logic, make sure there are no errors of any kind including view-only errors (like binding exceptions or ValidationRule errors). 
        return base.ValidateData() && this.ViewErrorCount == 0;
    }

ViewErrorCount 是一个简单的 int,当我如上所述捕获错误时,我会更新它。