【问题标题】:How to trap view-only validation errors in Catel?如何在 Catel 中捕获仅查看验证错误?
【发布时间】:2015-08-27 20:48:48
【问题描述】:

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

说明:

我有一个 Catel MVVM 窗口(使用 DataWindow 和具有模型属性的视图模型实现。)

模型属性是一个整数:

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

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

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

在视图中,有一个绑定到Foo 的文本框。当用户在文本框中输入非整数值时,绑定过程自然会出错,并且由于文本框将ValidatesOnExceptions设置为true,Catel信息消息栏出现如下:

我必须解决的两个问题:

  • 我需要一条自定义错误消息(“无法转换值 117.228”不会在此处显示。)
  • WarningAndErrorValidator 确实发现了错误,但DataWindow OK 按钮仍处于启用状态,并且我能够“保存”视图模型。当出现任何错误时,我需要禁用 OK,即使它们没有进入视图模型。

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

  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 绝对是“解决方法”解决方案,因为这意味着我在视图模型中需要这样的东西(请原谅伪代码...):

    [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 的文档中没有看到任何表明支持该方法的内容。我错过了一个简单的解决方案吗?

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

【问题讨论】:

    标签: wpf validation mvvm data-binding catel


    【解决方案1】:

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

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

    【讨论】:

    • 您是说我可以添加第二个 WarningAndErrorValidator 或仅在我假设的基类(DataWindow 的子类)中为现有的 Validation 事件添加一个新处理程序?
    • 没关系,我想我明白为什么我应该声明第二个验证器控件。因为不能保证DataWindow 会创建第一个。
    【解决方案2】:

    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,当我如上所述捕获错误时会更新它。

    【讨论】:

    • 你可能是对的。距离我们编写 WarningAndErrorValidator 已经有一段时间了(几年)。但是,如果 WarningAndErrorValidator 也可以捕获视图验证,那将是一个很好的补充(因此我们可以单一访问视图验证)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-17
    • 1970-01-01
    • 2011-03-16
    • 1970-01-01
    • 2018-03-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多