IDataErrorInfo与ValidationRule vs Exception

WPF*_*ser 19 wpf idataerrorinfo

任何人都可以告诉我哪种方法更适合WPF中的验证.

  1. 实现IDataErrorInfo
  2. 创建ValidationRule
  3. 抛出例外

在性能,内存泄漏,代码可维护性和重用方面.

Jus*_*ill 23

这是一种复杂的请求,老实说,它可能会根据偏好而不是其他任何因素而变化.但是,这是我的理解:

  • 性能:除非你的其他实现是可怕的,否则异常几乎每次都会丢失.抛出/捕获循环有很大的开销.(轶事:我有一个'必须是一个数字'检查是一个例外,当它失败时,它"滞后"UI显着的时间,但当转换为ValidationRule时,它实际上是即时的.)
  • 内存泄漏:这取决于验证规则或IDataErrorInfo实现的完成方式.
  • 代码可维护性,重用性:当然,这是有趣的部分.您真正应该问的是"何时使用ValidationRule代替IDataErrorInfo,反之亦然?"

ValidationRules比IDataErrorInfo早(我相信后者是在.Net 3.5中引入的).仅基于此,似乎WPF团队更喜欢IDataErrorInfo.但事实是,它们是为不同的事物而建造的.如果您有MVVM或等效模式,则IDataErrorInfo优于模型中的错误(例如,负年龄),而ValidationRules优于视图中的错误(例如,年龄为☃).当然可以让ValidationRules执行"业务逻辑"检查,或让IDataErrorInfo告诉你"unicode snowman不是一个有效的年龄",但你可能(可能)通过保持这种模式获得最佳的可维护性.

但是,除了初始测试之外,不要使用异常进行验证,以确定您应该测试的确切条件.

  • 今天正在阅读IDataErrorInfo - 似乎它比ValidationRule更旧 - 似乎IDataErrorInfo接口自Framework 1.1以来一直存在(http://msdn.microsoft.com/en-us/library/system.componentmodel.idataerrorinfo_properties(v= VS.71).aspx)但是自Framework 3.0以来的ValidationRule.不要认为它从根本上改变了你的答案 (5认同)
  • 在我看来,ValidationRule 甚至可以在设置属性之前拦截 Binding 过程并执行验证。而 IDataErrorInfo 或 INotifyDataErrorInfo 要求属性设置成功(通过绑定过程)。在简单的情况下,例如验证输入的文本是否为数字。我找不到任何方法让 IDataErrorInfo 和 INotifyDataErrorInfo 在这种情况下工作,因为如果输入的文本不是数字(可转换为模型中的某些数字类型),则该属性将***永远不会被设置,所以看起来只有 ValidationRule 有效 (2认同)

Mah*_*esh 6

使用异常进行错误处理并不是一个好主意.使用异常会降低性能.这是选择和实现IDataErrorInfo或创建ValidationRule的问题.

IDataErrorInfo的

  • 验证逻辑保持在视图模型中,易于实现和维护
  • 完全控制viewmodel中的所有字段

验证规则

  • 在单独的类中维护验证规则
  • 增加可重用性.例如,您可以在整个应用程序中实现必需的字段验证类重用它.

我的意见是,对于常见的验证,如必要的字段验证,电子邮件地址验证,您可以使用验证规则.如果您需要进行范围验证等自定义验证,或使用IDataerrorinfo进行自定义验证.


Pet*_*iho 6

我对这个话题的看法与其他两个答案中提出的观点略有不同:

验证规则

  • 这适用于需要在更新绑定源之前完成的验证。您可能喜欢这样做的原因包括能够向用户显示特定的错误消息,尤其是与数据转换前的值相关的消息,或验证必须转换的数据。

  • 正如其他答案中所指出的,在多个控件之间共享验证也更容易一些,因为您可以执行诸如创建ValidationRule用于多个绑定BindingGroup的单个的操作,或者使用 a来提供一次ValidationRule检查多个绑定的单个。

IDataErrorInfoINotifyDataErrorInfo

  • 这将验证放入视图模型中,适用于允许将非法值存储在视图模型中的场景。可以通过该界面向用户提供特定的错误消息。

  • 验证可用于视图模型实现的任何客户端,为此类验证提供更好的重用。

  • 验证规则的重用不太方便,但无论如何也不是不可能。您只需要实现自己的辅助方法或对象即可根据需要执行验证。

例外

  • 基于性能问题,其他答案避免了验证异常。但是,根据我的经验,UI 场景中的异常处理通常很好。尽管异常处理有额外的开销,但它的发生速度仍然比用户能够注意到的要快(尽管有未经证实的“轶事”)。

  • 异常的一个重要方面是它为您提供了在视图模型上实现错误通知接口的许多好处,同时仍然防止在视图模型属性上设置无效值。换句话说,您可能ValidationRule会遇到过早IDataErrorInfo发生和过晚发生的验证场景。从属性设置器抛出异常将解决这些情况。

底线:每种验证技术都有其优缺点,适用于特定场景。没有一个统一优于其他任何一个。这在很大程度上取决于您尝试进行哪种验证,以及您希望在哪里查看该逻辑的执行情况。