如何将数据绑定对象的组合框字段绑定到数据源并且仍然允许空值?

发布于 2024-07-21 12:36:04 字数 265 浏览 2 评论 0原文

我有一个绑定到客户对象的表单数据,其中一个字段是代表“类型”的可为空 int。 这显示为组合框,并且该组合框绑定到“类型”表。

当将空类型的客户加载到表单的数据源中时,组合框不显示任何值,但单击它后,您必须选择一个值。 表单/组合框永远不会让您更改回空白项(以表示客户对象上的“null”)。

我不希望数据库中出现“虚拟行”,目前通过添加虚拟对象并在提交事件中将其清空来实现此目的(不干净!)。

是否可以干净地完成此操作,并与可为空的主键保持一致?

I have a form databound to a customer object, and one of the fields is a nullable int representing a "type". This is displayed as a combobox, and the combobox is bound to the "Types" table.

When a customer with a null type is loaded into the form's datasource, the combo box displays no value, but then upon clicking it you must select a value. The form/combobox will never let you change back to a blank item (to represent "null" on the customer object).

I don't want "dummy rows" in the database, and currently do this by adding a dummy object, and nulling it out in a submit event (not clean!).

Is it possible to do this cleanly, keeping with the nullable primary key?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

乖乖 2024-07-28 12:36:04

有关可空数据绑定的其他链接和资源:

我被告知并且到目前为止已经成功,您应该在数据库数据源和 UI 之间有一个业务对象层,您可以在其中按照 shhkalpesh 的建议添加一个项目,而不必担心它进入数据库。

Jez Humble 在帖子和评论的底部提供了一些有关绑定可空类型的信息。它建议如果“您显式地将 DataSourceUpdateMode 设置为 DataSourceUpdateMode.OnPropertyChanged”,则可以绑定到可为 null 的类型。

另一篇关于数据绑定可为空类型的文章:代码的乐趣 - WinForms.NET 中的数据绑定和可为空类型

也许这段用于绑定可为空的 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);

    }

Additional links and resources concerning nullable databinding:

I've been told and so far it has panned out, that you should have a layer of business objects in between your database datasource and your UI where you could just add an item as shahkalpesh recommends without concern of it going into the database.

Jez Humble has some information on binding nullable types at the bottom of this post and in comments Where it suggests binding to nullable types is doable if "you explicitly set the DataSourceUpdateMode to DataSourceUpdateMode.OnPropertyChanged".

Another article on databinding Nullable types: The Joy of Code - Databinding and Nullable types in WinForms.NET

Maybe this code for binding a nullable DateTimePicker could help you find addditional solutions for this or other nullable issues.

Also check out Dan Hannan for the source of where I came up with my extension method.

/// <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);

    }
不知所踪 2024-07-28 12:36:04

如果您的主要目标是将组合恢复为空白并将值恢复为 null,则只需在编辑行时按 Ctrl+0 即可。

我花了两天的时间进行了疯狂的研究和心脏病发作的风险,只是为了在某个小帖子中找到这个隐藏的东西。

If your main goal is to restore the combo to blank and the value to null, just press Ctrl+0 when editing the row.

It took me two days of frantic research and heart attack risk just to find this out hidden in a small post somewhere.

夜吻♂芭芘 2024-07-28 12:36:04

用于绑定到类型组合的数据源可以再有 1 个带有 NULL 值的条目。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
TypeID   Name
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1        Business
2        Government
-1       NULL

您可以为没有类型的客户存储 -1(如果允许客户不需要有类型)。

The datasource which is used to bind to the Type combo, could have 1 more entry with NULL value in it.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
TypeID   Name
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1        Business
2        Government
-1       NULL

You could store -1 for Customer who doesn't have a type (if it is allowed that a customer need not have a type).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文