代码之家  ›  专栏  ›  技术社区  ›  David Hall

WinForms数据绑定和外键关系

  •  6
  • David Hall  · 技术社区  · 16 年前

    我正在开发一个winforms应用程序(.net 3.5,没有wpf),我希望能够在数据绑定的DataGridView中显示外键查找。

    这种关系的一个例子是,我有一个医嘱行表。订单行与产品具有外键关系,而产品又与产品类型具有外键关系。

    我希望有一个数据绑定的DataGridView,其中每一行表示一个订单行,显示该行的产品和产品类型。

    用户可以直接向网格添加或编辑医嘱行,并从ComboxColumn中为医嘱行选择产品-然后应更新ProductType列,在同一行中显示所选产品的ProductType。

    到目前为止,我发现最适合的方法是引入一个表示订单行的域对象,然后将DataGridView绑定到这些订单行的集合。然后,我将属性添加到公开产品和productType的orderline对象中,并引发相关的notifypropertychanged事件以使所有内容保持最新。然后,在我的orderline存储库中,我可以连接这个orderline对象和数据库中三个表之间的映射。

    这对数据绑定方面很有用,但是必须手工编写所有这些代码或在存储库中进行映射似乎很糟糕。我以为nHibernate可以帮助完成这个连接,但在处理所有外键之间的映射时,它们似乎工作正常(订单行产品的foreign key查找基于外键创建正确的产品对象),直到我尝试进行数据绑定,我才能够获取数据绑定ID列来更新我的pr。产品或产品类型对象。

    我的一般方法是正确的吗?如果是,什么是映射问题的好解决方案?

    或者,是否有更好的数据绑定行解决方案,包括我甚至没有考虑过的外键查找?

    5 回复  |  直到 16 年前
        1
  •  2
  •   Garo Yeriazarian Changal Rayudu    16 年前

    我认为您遇到的问题是,当您绑定到网格时,不足以支持inotifyPropertiesChanged,但您必须在 IBindingList 实现并确保重写并为 SupportsChangeNotification 财产。如果您不为此返回true,网格将不会查找它来了解数据是否已更改。

    在.NET 2.0+中,可以使用 BindingList 类,这将处理大部分的麻烦(只是不要忘记重写并为SupportsChangeNotification属性返回true)。

    如果用于数据绑定的类具有集合属性(如IBindingList或BindingList),则可以将外键网格直接绑定到该属性。在窗体设计器中配置绑定时,只需选择Collection属性作为网格的数据源。它应该“只起作用”。唯一的秘密部分是确保以正确的方式处理空集合或空集合。

        2
  •  1
  •   Rob Cooper    16 年前

    欢迎使用StackOverflow:)

    通常,您要做的是将下拉列表中的信息基于两个值 ValueMember and DisplayMember .

    value member是实际控件值的来源(这将是订单行中的键值),display member是显示给用户的值,而不是值(这将是fk值)。

    是否没有特别的原因不能只返回所需的所有数据并设置这些属性?

        3
  •  0
  •   urini    16 年前

    下面是一个演示数据绑定的“如何操作”视频:

    http://windowsclient.net/learn/video.aspx?v=52579

        4
  •  0
  •   Bevan    16 年前

    嗯,我不知道DataGridView是否支持它,但是当您进行常规WinForms数据绑定(例如,到常规文本框)时,可以使用 属性路径 浏览对象关系。

    像这样:

    myTextBox.DataBindings.Add("Text", anOrderLine, "OrderedPart.PartNumber");
    

    如果这在你的情况下也能奏效,那就值得一看了。

        5
  •  0
  •   David Hall    16 年前

    我最初的问题显然不清楚,对此很抱歉。

    一般来说,问题不在于数据绑定到DataGridView,也不在于DataGridView ComboBoxColumn的实现——正如那些已经正确回答的人所说,这在网络上有很好的记录。

    我一直在尝试解决的问题是更新通过关系向下钻取的属性。

    在我的订单示例中,当我更改“产品”列的值时,“产品类型”列不会被更新-即使在代码中,我正在设置属性并触发NotifyPropertyChanged事件。(在调试中,我去了所有正确的地方)

    在反复摸索之后,我意识到,当我直接设置datasource的“product type”属性,而不是将其设置在“product”setter中时,这甚至都不起作用。

    另一件我认为让我回到正轨的事情是,当我提供一个以主形式创建的模拟数据处理层时,一切都可以正常工作。

    另外,当我把NHibernate制作的IList复制到一个IBindingList时,一切又恢复正常。

    所以 问题是,我认为线程和notifypropertychanged事件在使用某些数据源时会以某些方式丢失(希望我能比这更明确!)

    我将继续研究更好的方法来解决这个问题,而不是将ilist复制到ibindinglist中-也许我需要了解线程编组。

    编辑

    我现在已经开发了一种解决方案,它解决了这个问题,并且认为我理解了让我困惑的地方——基本上,除了基本属性数据绑定以外的任何东西都不能很好地处理那些不是从bindingList派生的列表——当我试图将数据绑定到触发链接的notifypropertychanged事件的属性时,事情就变得一团糟了。我和艾尔的事情都输了。

    我现在使用的数据访问解决方案是使用Rob Conery的变体 IRepository 模式,将我的集合返回到我所创建的自定义类绑定,从bindingList派生的SortableBindingLazylist实现了排序核心方法,并将其内部列表存储为查询,从而延迟了列表的具体化。