我想知道在绑定到Winforms中的int
时是否有办法处理CheckBox
类型的可空值。
采用以下示例类:
public class TestClass
{
public Nullable<int> NULLABLE_INT_VALUE { get; set; }
public int NON_NULLABLE_VALUE { get; set; }
}
我有一个继承自标准复选框的组件,允许您传递一个对象(即类实例)和一个属性名称,并将对该复选框设置一个DataBinding:
public void FSetDataBinding(object BindingObject, string FieldName)
{
Binding ControlBinding = new Binding("Checked", BindingObject, FieldName) { NullValue = false };
ControlBinding.DataSourceUpdateMode = DataSourceUpdateMode.OnPropertyChanged;
ControlBinding.Format += (s, e) => { e.Value = e.Value.ToString() == "1"; };
ControlBinding.Parse += FormDBCheckBox_Parse;
DataBindings.Add(ControlBinding);
}
private void FormDBCheckBox_Parse(object sender, ConvertEventArgs e)
{
if((bool)(e.Value))
{
e.Value = "1";
}
else
{
e.Value = "0";
}
}
如果我创建两个复选框控件(分别为chkNullableValue
和chkNonNullableValue
),我可以将它们绑定到TestClass(我们假设TestClass是数据库表的EF版本:
TestClass IAmATest = new TestClass() { NULLABLE_INT_VALUE = 1, NON_NULLABLE_VALUE = 0 }
chkNullableValue.FSetDataBinding(IAmATest, "NULLABLE_INT_VALUE");
chkNonNullableValue.FSetDataBinding(IAmATest, "NON_NULLABLE_VALUE");
两个属性都来自同一个对象,并以完全相同的方式绑定;但是,当我尝试检查绑定到可空值的框时,由于某种原因,(set;)
访问器永远不会被击中属性。会发生什么,在表单上,框似乎被检查;但是,由于该框的基础属性尚未更新,下次格式化控件进行显示时,e.Value
仍然是"0"
,并且该框将“取消”检查&#39;本身。这也意味着调用SaveChanges()
并不会更新该值,因为它在技术上从未更新过。
此处还需要注意以下内容:是的,NullValue = false
针对创建的Binding
是真的;但是,在这种特定情况下,可空值已经具有值"0"
,因此实际上永远不会是null
(但可能在其他情况下)。
对于非可空属性,情况恰恰相反,这与我的预期完全相同;当您选中表单上的框时,NON_NULLABLE_VALUE
的值会更新并设置为"1"
FormDBCheckBox_Parse
的一部分,因此下次控件自行格式化时,ControlBinding.Format
返回"true"
并相应地设置checked属性。
我认为,如果某个东西是旗帜(因此,无论是在任何时候都是“关闭”还是“关闭”,那么空值不应该是&#39;是允许对数据库中的字段,所以最后我只是使值不可为空;但是,我想明白为什么我在使用可空类型时会遇到很多麻烦,以防我将来需要使用它。
答案 0 :(得分:1)
首先,正确的绑定配置适用于int
和int?
:
public void FSetDataBinding(object BindingObject, string FieldName)
{
Binding ControlBinding = new Binding("Checked", BindingObject, FieldName, true) { DataSourceNullValue = false };
ControlBinding.DataSourceUpdateMode = DataSourceUpdateMode.OnPropertyChanged;
DataBindings.Add(ControlBinding);
}
有些注意事项:
始终将Binding.FormattingEnabled
属性设置为true
(通过使用上面的构造函数重载或属性setter)。它正在修复一些旧的数据绑定错误,这些错误被保留用于向后兼容性&#34; - 不幸的是默认情况下。
与文档相反,NullValue
是在设置数据源值之前转换为null
的控件值。 DataSourceNullValue
是数据源值为null或为空时为控件设置的值。因此,当您取消选中绑定到nullable int
的复选框时,您需要使用更晚的其他函数,该属性将设置为null
。
您的Parse
方法不正确。在您将其转换为bool
时,它应该将控件值(int
)转换为您的案例中的数据源值(int?
或string
) 。由于默认bool
到int
转换(反之亦然)完全符合您的要求,因此我刚刚删除了自定义Format
和Parse
。