我正在开发一个使用 Catel 的 MVVM (4.0.0) 实现的程序。我有一个模型类,它作为一些业务逻辑 - 它必须遵守关于它的属性值之一的规则。
例如,假设我有一个 Trap
具有 TargetValue
的类和 CurrentValue
特性。对于此类,有一个规则必须强制执行 TargetValue
属性只能小于或等于 (<=) CurrentValue
. (CurrentValue
通过系统中的一些事件更新)。
陷阱暴露给用户(我有一个虚拟机,其中包含此类陷阱的列表并绑定(bind)到 UI 中的数据网格),她可以在其中更改 TargetValue
.
最初我想创建一个虚拟机来包装 Trap
对象实例并在那里执行规则,但由于该规则实际上与模型(或业务逻辑,也就是说,我可能在使用 Trap
类的任何地方都需要相同的规则)相关,所以我认为最好在属性中实现它TargetValue
的二传手(我将检查新值的有效性并重置或不更改基础字段值)。
所以据说我在 setter 中这样做(这甚至是正确的实现吗?) - 有没有办法通知VM(或直接UI)存在违规行为(例如通过设置单元格边框颜色或其他东西)?
我想也许我可以使用 RaisePropertyChanging
与 RaisePropertyChanged
合作那ObservableObject
暴露虽然看起来很麻烦。
这种模式有合适的方法吗?
谢谢,
托默
最佳答案
您不应该在 setter 中进行验证,因为 setter 负责设置对象的值。假设模型使用 INotifyPropertyChanged 和 IDataErrorInfo(或 INotifyDataErrorInfo),你可以用 Catel 做大事。
例如,在 ModelBase 中,您可以覆盖 ValidateFields 或 ValidateBusinessRules,甚至可以将自定义验证器应用于您的模型。然后 ModelBase 会自动为你实现变更通知和验证接口(interface)。
接下来,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 将观察它的通知并将 View 模型上的属性映射到模型,反之亦然。现在很酷的事情来了:它不仅映射了属性值,还映射了验证规则。这意味着此 View 模型足以满足您的 View ,并且您可以在模型中实现验证。
关于c# - 使用 Catel 将验证从模型传播到 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27226108/