首页 > 解决方案 > 使用 INotifyDataErrorInfo 处理转换异常

问题描述

我的视图中有一个文本框,用户可以在其中输入 TCP 端口值。文本框直接绑定到模型的端口属性(类型为 Int32),因为 ViewModel 提供了完整的绑定模型。模型是从 ObservableObject 继承的,因此直接绑定到它运行良好。

我在模型中使用 INotifyDataErrorInfo,并且 Port 属性验证属性设置器中的值(它必须大于 0)。

我的视图中有一个按钮,它绑定到模型的 HasError() 方法并根据 HasError() 的布尔返回值设置其 IsEnabled 状态

现在的问题是,如果用户键入“Hello world”,WPF 绑定引擎会抛出异常。在这种情况下,永远不会执行属性设置器,因此 HasError() 永远不会针对这种无效输入更改为 true。

我当然可以为视图中的文本框设置“ValidatesOnExceptions = True”,以便在这种情况下至少让文本框显示其验证错误模板,但按钮仍然不会被禁用。

问题,推荐的解决方案是如何处理这些自动转换失败的情况,从而永远不会执行 ViewModel/Model 的验证?

我可以接受一个解决方案,其中验证在文本框字符串而不是 Int32 类型上执行,在 WPF 绑定引擎执行失败的自动类型转换为 Int32 之前执行。

我真正想避免的一个解决方案是让我的 ViewModel / Model 属性始终为字符串类型,验证 setter 中的字符串,然后尝试手动将其转换为正确的类型(在本例中为 Int32)。必须有一个更好的解决方案来避免所有这些手动转换。

使用 ValidationRules 时,可以告诉验证引擎在自动转换之前执行 ValidationRule。我真正想要的是一种在自动转换完成之前执行 INotifyDataErrorInfo 验证的方法。

标签: c#.netwpfvalidationdata-binding

解决方案


您遇到的困难说明了为什么您应该从您的视图直接绑定到您的模型。视图模型的重点是在视图和与底层模型交互的代理之间来回转换表示关注点。

例如:如果您的视图为端口提供了一个字符串,那么视图模型将对其进行验证并将其转换(如果有效)为模型的整数,或者通过任何错误通知机制通知视图无效输入。


推荐阅读