我有一个数据绑定到客户对象的表单,其中一个字段是表示“类型”的可为空的 int。这显示为组合框,并且组合框绑定到“类型”表。
将具有空类型的客户加载到表单的数据源中时,组合框不显示任何值,但是在单击它时,您必须选择一个值。表单/组合框永远不会让您改回空白项目(在客户对象上表示“空”)。
我不想要数据库中的“虚拟行”,目前通过添加一个虚拟对象并在提交事件中将其清空(不干净!)来做到这一点。
是否有可能干净地做到这一点,并保持可为空的主键?
我有一个数据绑定到客户对象的表单,其中一个字段是表示“类型”的可为空的 int。这显示为组合框,并且组合框绑定到“类型”表。
将具有空类型的客户加载到表单的数据源中时,组合框不显示任何值,但是在单击它时,您必须选择一个值。表单/组合框永远不会让您改回空白项目(在客户对象上表示“空”)。
我不想要数据库中的“虚拟行”,目前通过添加一个虚拟对象并在提交事件中将其清空(不干净!)来做到这一点。
是否有可能干净地做到这一点,并保持可为空的主键?
有关可空数据绑定的其他链接和资源:
有人告诉我,到目前为止它已经成功了,你应该在你的数据库数据源和你的 UI 之间有一层业务对象,你可以按照 shahkalpesh 的建议添加一个项目,而不用担心它会进入数据库。
Jez Humble 在这篇文章的底部和评论中提供了一些关于绑定可空类型的信息,如果“您明确地将 DataSourceUpdateMode 设置为 DataSourceUpdateMode.OnPropertyChanged”,它建议绑定到可空类型是可行的。
关于数据绑定 Nullable 类型的另一篇文章:代码的乐趣 - WinForms.NET 中的数据绑定和 Nullable 类型
也许此用于绑定可为空的 DateTimePicker 的代码可以帮助您找到针对此问题或其他可为空问题的其他解决方案。
另请查看Dan Hannan,了解我提出扩展方法的来源。
/// <summary>
/// From BReusable
/// </summary>
/// <param name="dtp"></param>
/// <param name="dataSource"></param>
/// <param name="valueMember"></param>
/// <remarks>With help from Dan Hanan at http://blogs.interknowlogy.com/danhanan/archive/2007/01/21/10847.aspx</remarks>
public static void BindNullableValue(this DateTimePicker dateTimePicker, BindingSource dataSource, String valueMember,bool showCheckBox)
{
var binding = new Binding("Value", dataSource, valueMember, true);
//OBJECT PROPERTY --> CONTROL VALUE
binding.Format += new ConvertEventHandler((sender, e) =>
{
Binding b = sender as Binding;
if (b != null)
{
DateTimePicker dtp = (binding.Control as DateTimePicker);
if (dtp != null)
{
if (e.Value == null)
{
dtp.ShowCheckBox = showCheckBox;
dtp.Checked = false;
// have to set e.Value to SOMETHING, since it's coming in as NULL
// if i set to DateTime.Today, and that's DIFFERENT than the control's current
// value, then it triggers a CHANGE to the value, which CHECKS the box (not ok)
// the trick - set e.Value to whatever value the control currently has.
// This does NOT cause a CHANGE, and the checkbox stays OFF.
e.Value = dtp.Value;
}
else
{
dtp.ShowCheckBox = showCheckBox;
dtp.Checked = true;
// leave e.Value unchanged - it's not null, so the DTP is fine with it.
}
}
}
});
// CONTROL VALUE --> OBJECT PROPERTY
binding.Parse += new ConvertEventHandler((sender, e) =>
{
// e.value is the formatted value coming from the control.
// we change it to be the value we want to stuff in the object.
Binding b = sender as Binding;
if (b != null)
{
DateTimePicker dtp = (b.Control as DateTimePicker);
if (dtp != null)
{
if (dtp.Checked == false)
{
dtp.ShowCheckBox = showCheckBox;
dtp.Checked = false;
e.Value = (Nullable<DateTime>)null;
}
else
{
DateTime val = Convert.ToDateTime(e.Value);
e.Value = val;
}
}
}
});
dateTimePicker.DataBindings.Add(binding);
}
如果您的主要目标是将组合恢复为空白并将值恢复为空,则只需在编辑行时按 Ctrl+0。
我花了两天时间进行疯狂的研究和心脏病发作的风险,才发现它隐藏在某个地方的一个小帖子中。
用于绑定到 Type 组合的数据源可能还有 1 个条目,其中包含 NULL 值。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 类型 ID 名称 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1 业务 2 政府 -1 空
您可以为没有类型的客户存储 -1(如果允许客户不需要类型)。