23

我目前正在使用 winforms 数据绑定来连接数据编辑表单。我通过 CodeSmith 使用 netTiers 框架来生成我的数据对象。对于允许空值的数据库字段,它会创建可空类型。我发现使用 winforms 数据绑定控件不会正确绑定到可为空的类型。

我在网上看到了一些解决方案,建议人们创建新的文本框类来处理可以为空的类型,但这可能会很痛苦,不得不在我已经创建的表单上换掉文本框。

最初我认为使用扩展方法来做到这一点会很棒。基本上为文本框类创建一个扩展属性并绑定到它。从我有限的扩展方法经验和在线检查来看,您似乎无法进行扩展属性。据我所知,绑定必须通过属性,因为它需要能够获取或设置值,因此扩展方法不起作用。

我很想找到一种干净的方法来使用扩展方法之类的方法来改造这些表单,但是如果我必须创建新的文本框和组合框控件,我会这样做。

由于需要在 Windows 2000 上运行,我的项目目前仅限于 .Net 2.0。

有什么建议么?

4

4 回答 4

49

在上面引用的文章的评论部分,其中一位海报提出了一个简单的解决方案。

而不是绑定:

textBox1.DataBindings.Add("Text", myClass, "MyTextProperty");

绑定:

textBox1.DataBindings.Add("Text", myClass, "MyTextProperty", true, DataSourceUpdateMode.OnPropertyChanged, string.Empty); 
于 2010-08-19T17:53:45.027 回答
6

我自己偶然发现了这个问题,这真是令人头疼。

绑定可空类型的有趣之处在于,DataGridView 可以毫无问题地处理它们——只是文本框会导致问题。

这非常讨厌 - 当您在文本框中有一个空值并且您似乎也无法离开它时,它甚至似乎阻止关闭表单。

所以,这不是一个很好的答案,但我的建议是尝试坚持使用 datagridviews 来处理表单上的可为空类型。

另一个建议是使用此处建议的“扩展器提供程序”,尽管我尚未对其进行测试:

编辑:现在已经下载了这个页面上的示例代码,它工作得很好。

http://www.thejoyofcode.com/Databinding_and_Nullable_types_in_WinForms.NET.aspx

于 2009-02-05T04:29:41.470 回答
2

哦,讨厌......我只能想到几种方法来实现这一点,而且它们都不是我所说的理想。

  • 第一个是为您的数据对象编写一个包装器,该包装器包含可空值,将所有可空值转换为空字符串。绑定到您的包装器对象。

  • 第二个是确保数据库中的所有值都不为空......再次,不理想

  • 您已经决定在这种情况下不可行的第三个是您创建一个自定义对象,该对象扩展文本框以添加可以绑定到可为空的属性。

  • 我能想到的第四个最理想的方式似乎是不可能的。创建一个扩展属性,允许您扩展所有文本框对象并绑定到该对象 - 但目前看来扩展属性是不可能的。在这种情况下,这种类型的功能似乎在 .NET 框架中特别有用。

于 2008-12-18T02:29:02.600 回答
0

来自WinForms.NET 中的数据绑定和 Nullable 类型

设想

  • 您有一个具有 Nullable 属性的实体类型。
  • 您有一个绑定到该属性的 TextBox。
  • 当用户清除 TextBox 中的文本时,您希望将属性的值设置为 null。

问题

清除绑定到 Nullable 类型的 TextBox 时,数据绑定的结果根本不会成功。

解决方案

在本文中,我将展示如何使用 Extender Provider 来做到这一点。

只需将 Component 类添加到您的项目中,该类也实现了 IExtenderProvider 接口

[ProvideProperty("NullableBinding", typeof(TextBox))]  
public partial class NullableExtender : Component, IExtenderProvider

ProviderProperty 属性表明,在将 NullableExtender 组件添加到您的 Form 或 UserControl 时,所有的 TextBox 都将具有一个名为 NullableBinding 的附加属性。在 VS.NET 设计器中它看起来像这样:

NullableBinding 属性

现在为这个属性实现一些功能:

private Dictionary<Control, Boolean> _nullables = new Dictionary<Control,bool>();

/// <summary>
/// This is the get part of the extender property.
/// It is actually a method because it takes the control.
/// </summary>
/// <param name="control"></param>
[DefaultValue(false),
Category("Data")]
public bool GetNullableBinding(Control control)
{
    bool nullableBinding = false;
    _nullables.TryGetValue(control, out nullableBinding);
    return nullableBinding;
}

/// <summary>
/// This is the set part of the extender property.
/// It is actually a method because it takes the control.
/// </summary>
/// <param name="control"></param>
/// <param name="nullable"></param>
public void SetNullableBinding(Control control, bool nullable)
{
    if (_nullables.ContainsKey(control))
        _nullables[control] = nullable;
    else
        _nullables.Add(control, nullable);
    if (nullable)
    {
        // Add a parse event handler.
        control.DataBindings["Text"].Parse += new ConvertEventHandler(NullableExtender_Parse);
    }
}

/// <summary>
/// When parsing, set the value to null if the value is empty.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void NullableExtender_Parse(object sender, ConvertEventArgs e)
{
    if (e.Value.ToString().Length == 0)
    {
        e.Value = null;
    }
}

实际完成上述技巧的代码是为数据绑定 Parse 事件添加事件处理程序。如果值为空字符串,则事件处理程序只需将值设置为 null,并且数据绑定成功。

该属性的默认值设置为 false,因为大多数属性不是 Nullable 类型,我建议不要将这些属性的 NullableBinding 设置为 true ... ;)

于 2018-12-27T13:12:47.730 回答