我知道我在这里使用的是日落技术,但我仍然想找到解决问题的方法。
我有一个包含一些简单字段的实体。我可以在这样的表单上绑定文本框
nameTextBox.DataBindings.Add(new Binding("Text", entity, "Name"));
我对日期字段做了同样的事情,
evaluationDatePicker.DataBindings.Add(new Binding("Value", entity, "EvaluationDate"));
只要 EvaluationDate 属性是 DateTime 类型,这也可以正常工作。
但是,如果我现在修改实体并使 EvaluationDate 可以为空,则绑定变为单向。也就是说,控件反映了属性值(只要它不为空),但当我在 UI 中选择另一个日期时,它不会更新实体。
与最近的 Windows 窗体策略一致,即不抛出异常,而是假装一切都很好,即使事情失败了(我书中的一个主要烦恼;Form_Load 现在也只是吞下异常,尽管在这种情况下,我们当然已经超越了 Form_Load发生错误)。所以实际上我什至无法判断它是否正在尝试做任何事情,但我必须假设它是,因为只要属性不可为空,双向绑定就可以正常工作。
我该如何克服呢?
我要做的是为应用程序中的演示者编写一个基类,该基类能够基于简单的命名约定对控件进行数据绑定。演示者知道,对于 TextBox,它应该绑定 Text 属性,对于 CheckBox,它应该绑定“Checked”,等等。属性和控件之间的映射是按约定完成的 - 呈现字段的控件应该与字段和控件类型具有相同的名称。因此,在 TextBox 中呈现的“Name”映射到“NameTextBox”(这是我无论如何都喜欢使用的约定 - 我从来不明白为什么人们仍然喜欢专门用于 GUI 控件的前缀,但没有其他类型的代码!?)和复选框中的“IsMarried”将变为“IsMarriedCheckBox”。
所有这些都允许演示者提供一种方法,该方法接受一个对象、“数据源”和一个要绑定的控件所在的容器。与必须使用绑定源和编写代码相比,这使得向屏幕添加一堆字段的工作非常快速,像我的解决方案不提供任何编译器检查,并且确实意味着很容易通过错误类型和属性重命名来破坏事情。
但是为了制作我的小 PoC,我想知道我能用它处理什么,以及什么样的事情仍然需要其他解决方案。如果它可以支持可为空类型的属性,那么整个事情将更有价值,因为我们经常使用它们。(我也不想停止使用它们;将“有一个值”的概念捆绑在一起,如果是的话,“哪个值”是优雅的,并且可以减少代码,以及更多的编译器帮助。)
有办法吗?有什么可以勾搭的吗?或者可以创建我自己的泛型类型来替换 Nullable<T>?由于我不明白为什么它不工作,我必须做任何事情,所以很难想象有什么值得尝试解决它。