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

Posted

技术标签:

【中文标题】WPF 数据绑定和验证规则最佳实践【英文标题】:WPF Data Binding and Validation Rules Best Practices 【发布时间】:2010-09-08 23:36:42 【问题描述】:

我有一个非常简单的 WPF 应用程序,我在其中使用数据绑定来允许编辑一些自定义 CLR 对象。我现在想在用户单击保存时进行一些输入验证。但是,我读过的所有 WPF 书籍并没有真正为这个问题投入任何篇幅。我看到您可以创建自定义 ValidationRules,但我想知道这是否会超出我的需求。

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

【问题讨论】:

【参考方案1】:

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

阅读更多here

【讨论】:

我还找到了 Cinch 框架 (cinch.codeplex.com),其中包含 WPF+MVVM 中的最佳实践验证演示,并使用 IDataErrorInfo 在 .NET 4.5 中,您可以使用 INotifyErrorInfo,它允许您返回对象而不仅仅是字符串。【参考方案2】:

同时检查this article。据说微软从他们的模式和实践中发布了他们的Enterprise Library (v4.0),他们涵盖了验证主题,但天知道他们为什么不包括对 WPF 的验证,所以我要引导你的博客文章解释了作者做了什么来适应它.希望这会有所帮助!

【讨论】:

【参考方案3】:

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

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

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

【讨论】:

【参考方案4】:

您可能对 WPF Application Framework (WAF)BookLibrary 示例应用程序感兴趣。它展示了如何在 WPF 中使用验证,以及在存在验证错误时如何控制“保存”按钮。

【讨论】:

【参考方案5】:

来自 MS 的Patterns & Practices documentation:

数据验证和错误报告

您的视图模型或模型通常是 需要执行数据验证 并发出任何数据验证的信号 视图的错误,以便用户 可以采取行动纠正它们。

Silverlight 和 WPF 提供支持 用于管理数据验证错误 改变个人时发生的 绑定到控件的属性 在视图中。对于单一属性 数据绑定到控件, 视图模型或模型可以发出数据信号 属性内的验证错误 setter 通过拒绝传入的坏 值并抛出异常。如果 ValidatesOnExceptions 属性 数据绑定为真,数据 WPF 和 Silverlight 中的绑定引擎 将处理异常并显示 给用户的视觉提示 数据验证错误。

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

文档继续解释如何实现 IDataErrorInfo 和 INotifyDataErrorInfo。

【讨论】:

当我看到抛出异常的建议时,我一开始很担心。很高兴看到后面是“应尽可能避免以这种方式抛出带有属性的异常” 还应该注意的是,微软的一些木偶决定不在 .net4 中包含 INotifyDataErrorInfo,而只在 silverlight 中包含。这是一种痛苦.. @al3891- 这将在 .NET 4.5 中排序- msdn.microsoft.com/en-us/library/… @aL3891 缺少的 INotifyDataErrorInfo 有什么替代方法吗?【参考方案6】:

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

如果您的业务类是通过对 WCF/XmlWeb 服务的引用创建的存根类,那么您不能/不得使用 IDataErrorInfo 也不能抛出与 ExceptionValidationRule 一起使用的异常。相反,您可以:

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

【讨论】:

我知道这已经过时了,但我希望 Alex 能够做出回应。这也是我得出的结论,但问题是您必须为(例如)ValidationRule 中不能大于 100 的“Age”属性编写一些验证,然后在 IDataErrorInfo 接口中重复相同的逻辑,这重复了逻辑。有什么办法吗? 你在哪里复制逻辑?在某种服务器验证中?我猜您的评论是您在 UI 中使用 IDataErrorInfo 进行验证并在业务对象中复制验证,不是吗?如果是这样,那么在双方都进行验证是正确的。业务对象不能信任 UI,必须执行自己的验证(虽然看起来是重复的) 不,验证逻辑的重复出现在 IDataErrorInfo 和自定义验证规则中...因为自定义验证规则是在数据实际更新为绑定对象之前验证数据的唯一方法,该验证(年龄必须低于 100)需要在 IDataErrorInfo 中定义以返回“每个字段”消息,但也必须在自定义验证规则中实现。有意义吗?

以上是关于WPF 数据绑定和验证规则最佳实践的主要内容,如果未能解决你的问题,请参考以下文章

WPF 绑定组验证

Java 数据绑定最佳实践

WPF 数据验证中的绑定失败

WPF---数据绑定之ValidationRule数据校验

Combine + SwiftUI 中的最佳数据绑定实践?

2021-09-15 WPF上位机 16-属性绑定(数据验证)