c# - 使用 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 验证的方法。
解决方案
您遇到的困难说明了为什么您不应该从您的视图直接绑定到您的模型。视图模型的重点是在视图和与底层模型交互的代理之间来回转换表示关注点。
例如:如果您的视图为端口提供了一个字符串,那么视图模型将对其进行验证并将其转换(如果有效)为模型的整数,或者通过任何错误通知机制通知视图无效输入。
推荐阅读
- php - 如何从 opencart3 管理面板中的 MySQL Query 获取另一列值?
- android - 单击按钮时没有出现 ImageView
- linux - Unity:Linux 上所有网格过滤器上缺少网格
- azure - 如何使用 Powershell 7 将保留的 IP 地址分配给 Azure 上的云服务?
- android - 杀死带有 ContentProvider 代码的应用程序时无法找到 ContentProvider 信息
- parsing - 从 Scrapy 蜘蛛类中的另一个文件调用 HTML 标签并解析它们
- javascript - 使用 html-dock-js-typescript 生成的 word 文件中的问题
- c# - 如何让单人游戏中的角色走在特定的路线上?
- python-3.x - Python(3.x): print(string , end='') 导致突出显示模符号 %
- python-3.x - 当我抓取数据 python selenium 时,tbody 不会出现