繁体   English   中英

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

[英]Propagate validation from Model to View with Catel

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

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

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

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

因此,据说我是在setter中完成的(甚至是正确的实现吗?)-是否可以通过某种方式通知VM(或UI)是否存在违规情况(例如,通过设置单元格边框颜色或其他方式)?

我以为也许可以将ObservableObject公开的RaisePropertyChangingRaisePropertyChanged一起RaisePropertyChanged ,尽管看起来很麻烦。

是否有适当的方式来实现这种模式?

谢谢,

托默

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

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

接下来,VM包含陷阱,例如下面的vm(请注意,此示例使用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的功能之后,由于操作的顺序,似乎通过“常规”验证流程无法解决问题:

  • 财产设定者
  • ValidateFields
  • 错误信息已准备好用于VM

解决方案应如下:

  • CurrentValue属性设置器应该是私有的,这样就不能绑定到(直接或通过使用装饰等通过VM进行绑定)
  • 添加到TrapIDataErrorInfo (或INotifyDataErrorInfo )实现
  • 实现SetCurrentValue函数,该函数验证数据并仅在合法的情况下进行设置。 否则,请调用IDataErrorInfo机制。
  • 在用户界面中-绑定到功能而不是属性(例如http://msdn.microsoft.com/zh-cn/library/aa348824(v=vs.110).aspx

这种方法应满足上述要求-属性值在任何使用情况下都不会无效,但仍可以与UI进行协调。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM