使用 Catel 将验证从模型传播到视图

本文关键字:传播 视图 模型 Catel 验证 使用 | 更新日期: 2023-09-27 18:32:48

我正在使用Catel的MVVM(4.0.0(实现开发一个程序。我有一个模型类,作为某些业务逻辑 - 它必须遵守有关其属性值之一的规则。

例如,假设我有一个具有TargetValueCurrentValue属性的Trap类。对于此类,有一个规则必须强制 TargetValue 属性只能小于或等于 (<=( CurrentValue 。(CurrentValue通过系统中的某些事件更新(。

陷阱

向用户公开(我有一个 VM,其中包含此类陷阱的列表并绑定到 UI 中的数据网格(,她可以在其中更改TargetValue

最初,我虽然创建一个 VM 来包装Trap对象实例并在那里强制执行规则,但由于该规则实际上与模型(或业务逻辑,也就是说,我可能在我使用类Trap任何地方都需要相同的规则(我认为最好在属性库中实现它TargetValue(我将检查新值的有效性并重置或不更改基础字段值(。

所以据说我在 setter 中这样做(这甚至是一个正确的实现吗? - 有没有办法通知 VM(或直接 UI(存在违规(例如通过设置单元格边框颜色或其他方式(?

我想也许我可以与ObservableObject公开的RaisePropertyChanged合作使用RaisePropertyChanging,尽管它看起来很麻烦。

这种模式有合适的方法吗?

谢谢

托默

使用 Catel 将验证从模型传播到视图

您不应该在资源库中进行验证,因为资源库负责设置对象的值。假设模型使用 INotifyPropertyChanged 和 IDataErrorInfo(或 INotifyDataErrorInfo(,您可以使用 Catel 做大事。

例如,在模型库中,您可以覆盖 ValidateFields 或 ValidateBusinessRules,甚至可以将自定义验证程序应用于您的模型。然后,模型库将自动为您实现更改通知和验证接口。

接下来,虚拟机

包含陷阱,例如下面的虚拟机(请注意,此示例使用 Catel.Fody(:

public class MyTrapViewModel : ViewModelBase
{
    public MyTrapViewModel(Trap trap)
    {
        Argument.IsNotNull(() => trap);
        Trap = trap;
    }
    [Model]
    [Expose("CurrentValue")]
    [Expose("TargetValue")]
    private Trap Trap { get; set; }
}

在此示例中,您将 Trap 属性定义为模型。这意味着 Catel 将监视它的通知,并将视图模型上的属性映射到模型,反之亦然。现在来了一件很酷的事情:它不仅映射属性值,还映射验证规则。这意味着此视图模型足以满足您的视图,您可以在模型中实现验证。

在关于 Catel 功能的讨论之后,由于操作顺序,通过"常规"验证流程似乎在这里不起作用:

  • 属性设置器
  • 验证字段
  • 错误信息已准备好用于 VM

解决方案应该如下:

  • CurrentValue属性资源库应该是私有的,以便它不能绑定到(直接或通过 VM 使用修饰等(
  • 添加到TrapIDataErrorInfo(或INotifyDataErrorInfo(实现
  • 实现一个SetCurrentValue函数,该函数验证数据并仅在合法时才设置数据。如果没有,请调用IDataErrorInfo机制。
  • 在 UI 中 - 绑定到函数而不是属性(例如 http://msdn.microsoft.com/en-us/library/aa348824(v=vs.110(.aspx(

此方法应满足上述要求 - 属性值在任何用例中都不会无效,但仍然可以与 UI 协调。