WPF数据绑定和验证规则最佳实践


101

我有一个非常简单的WPF应用程序,其中使用了数据绑定以允许编辑某些自定义CLR对象。现在,我想在用户单击保存时添加一些输入验证。但是,我读过的所有WPF书籍都没有真正花任何时间解决这个问题。我看到您可以创建自定义的ValidationRules,但是我想知道这是否对我的需求来说是过大的。

所以我的问题是:在某处是否有一个好的示例应用程序或文章展示了验证WPF中用户输入的最佳实践?

Answers:


83

我认为新的首选方法可能是使用IDataErrorInfo

在这里阅读更多


3
我还找到了Cinch框架(cinch.codeplex.com),其中包括WPF + MVVM中的最佳实践验证演示,并使用IDataErrorInfo
Mark Heath

3
在.NET 4.5中,您可以使用INotifyErrorInfo,它允许您返回对象,而不仅仅是字符串。
彼得

24

从MS的模式和实践文档中

数据验证和错误报告

通常会需要您的视图模型或模型来执行数据验证并将任何数据验证错误通知给视图,以便用户可以采取行动来纠正它们。

Silverlight和WPF提供支持,用于管理更改绑定到视图中控件的单个属性时发生的数据验证错误。对于数据绑定到控件的单个属性,视图模型或模型可以通过拒绝传入的错误值并引发异常来指示属性设置器内的数据验证错误。如果数据绑定上的ValidatesOnExceptions属性为true,则WPF和Silverlight中的数据绑定引擎将处理该异常并向用户直观地提示存在数据验证错误。

但是,应尽可能避免以这种方式抛出带有属性的异常。另一种方法是在视图模型或模型类上实现IDataErrorInfo或INotifyDataErrorInfo接口。这些接口允许您的视图模型或模型对一个或多个属性值执行数据验证,并向视图返回错误消息,以便可以将错误通知用户。

该文档继续说明了如何实现IDataErrorInfo和INotifyDataErrorInfo。


3
起初我看到抛出异常建议时感到担心。很高兴看到之后“尽可能避免使用这种方式抛出属性异常”
kenwarner,2010年

22
还应注意,Microsoft的一些布偶决定不将INotifyDataErrorInfo包括在.net4中,而仅包括在Silverlight中。它是一种痛苦..
aL3891 2011年

5
@ al3891-这将在.NET 4.5〜分类msdn.microsoft.com/en-us/library/...
RichardOD

@ aL3891对于丢失的INotifyDataErrorInfo是否有其他选择?
AgentKnopf

10

个人而言,我正在使用异常来处理验证。它需要执行以下步骤:

  1. 在数据绑定表达式中,您需要添加“ ValidatesOnException = True”
  2. 在要绑定到的数据对象中,需要添加DependencyPropertyChanged处理程序,在其中检查新值是否满足条件-如果不满足,则恢复到对象的旧值(如果需要)并引发异常。
  3. 在用于在控件中显示无效值的控件模板中,可以访问“错误收集”并显示异常消息。

这里的技巧是仅绑定到从DependencyObject派生的对象。INotifyPropertyChanged的简单实现不起作用-框架中存在一个错误,该错误阻止您访问错误集合。


3

还要检查这篇文章。据说微软从他们的模式和实践中发布了他们的企业库(v4.0),其中涵盖了验证主题,但是上帝知道为什么他们不包括对WPF的验证,因此我将指导您的博客文章解释了作者的内容。做了适应它。希望这可以帮助!



0

如果您的UI直接使用您的业务类,则最好使用IDataErrorInfo,因为它使逻辑更接近其所有者。

如果您的业务类是由对WCF / XmlWeb服务的引用创建的存根类,则您不能/必须不使用IDataErrorInfo或将Exception抛出以与ExceptionValidationRule一起使用。相反,您可以:

  • 使用自定义ValidationRule。
  • 在WPF UI项目中定义一个局部类,并实现IDataErrorInfo。

1
我知道这已经很老了,但我希望Alex能够做出回应。这也是我得出的结论,但是问题是,您必须为“ Age”属性(例如)写一些验证,该属性不能大于ValidationRule中的100,然后在IDataErrorInfo接口中重复相同的逻辑,重复逻辑。有什么办法解决吗?
JFTxJ

您在哪里重复逻辑?在某种服务器验证中?根据您的评论,我猜您正在用UI中的IDataErrorInfo进行验证,并在业务对象中复制了验证,不是吗?如果是这样,那么在双方进行验证都是正确的。业务对象不能信任UI,必须执行自己的验证(尽管看起来重复)
Alex Pollan

不,验证逻辑的重复出现在IDataErrorInfo和“自定义验证规则”中...由于“自定义验证规则”是在实际更新为绑定对象之前验证数据的唯一方法,因此该验证(年龄必须较低那么必须在IDataErrorInfo中定义100)以返回“每个字段”消息,但还必须在自定义验证规则中实现。说得通?
JFTxJ 2013年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.