MVVM在View Model中检测Validation.HasError

时间:2012-05-22 09:45:54

标签: wpf

我使用MVVM并且使用IDataErrorInfo完成了大部分验证,而我的ViewModel具有IsValid属性,该属性检查需要验证的每个成员的有效性。但是我有几个绑定到int的文本框不能为空,所以我使用ValidationRule来警告用户(使用比#34;值更友好的消息无法转换&# 34; one)如果他们将该字段删空,显然属性设置器永远不会被调用,因此IDataErrorInfo代码不会被调用。

问题是我有一个Save按钮(这是一个RelayCommand),如果有任何验证错误我想要禁用它。因此该命令的CanExecute检查VM的IsValid属性。但显然如果用户空白我的int字段,IDataErrorInfo对它一无所知,并且当前该按钮不会被禁用。有没有一种方法可以让ViewModel检测到该错误?

我以为我在这里找到了解决方案 http://wpfglue.wordpress.com/2009/12/03/forwarding-the-result-of-wpf-validation-in-mvvm/ 但是把它翻译成C#我无法使它工作(从未调用过Coerce回调)。我还不太了解依赖属性和对象(对WPF来说很新),这个解决方案看起来很复杂。

我唯一能想到的就是摆脱验证规则并制作一个可以为空的int包装器,把TargetNullValue =''在绑定中然后我可以在IDataErrorInfo代码中检查它们是否为null。如果有更好的方法,我宁愿不这样做。

3 个答案:

答案 0 :(得分:1)

为什么不在viewmodel中使用字符串属性而不是int与IDataErrorInfo验证?在您的savecommand中,如果IDataErrorInfo当然没有错误,您可以安全地将字符串转换为int值。使用带有IDataErrorInfo的字符串属性是最简单的方法。

编辑:再想一想,如果不使用字符串属性,还有另一个问题。假设您有一个int属性,并且用户在文本框中设置了10。所以在你的viewmodel中你有10.现在用户删除10并在你的文本框中设置一个abc。你的viewmodel仍然得到10.,因为bindingconversationexception。这就是为什么我几乎使用字符串属性。公平地说,您可以使用文本框的行为来设置掩码,因此用户无法输入无效数据。

答案 1 :(得分:1)

我可以立刻想到两个强大的选择。一种是绑定到ViewModel中的字符串属性,而该属性又被编程为仅在确定字符串有效时才解析并存储基础'int'值。这可确保TextBox始终成功存储其数据绑定值。

第二种方法是截取视图中出现的ValidationExceptions,通过自定义行为将它们存储在ViewModel中。 This article基本上与您在问题中描述的完全相同。

答案 2 :(得分:0)

您可以尝试BindingGroups并对整个元素进行验证,而不仅仅是单个属性。我在模态对话框中使用它来创建项目,例如,在完成对话之前必须设置某些设置。这link详细解释了它。 This一个也非常详细。