【发布时间】:2019-02-18 07:24:32
【问题描述】:
我的视图中有一个文本框,用户可以在其中输入 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 验证的方法。
【问题讨论】:
-
什么问题的推荐解决方案是什么?显然,您的视图模型无法处理这种异常,因为它从未涉及。当您尝试将字符串转换为 int 时发生的异常已由框架为您处理,那么您的实际问题是什么?
-
是的,如何在自动转换之前执行验证。我更新了问题以更清楚。
-
在视图中使用 ValidationRule。请参考我的回答。
标签: c# .net wpf validation data-binding