6

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

这种关系的一个例子是我有一个 OrderLines 表。Orderlines 与 Products 具有外键关系,而 Products 又与 ProductTypes 具有外键关系。

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

用户可以直接向网格添加或编辑订单行,并从组合框列中为订单行选择产品——这应该会更新产品类型列,在同一行中显示所选产品的产品类型。

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

这适用于数据绑定方面,但必须在存储库中手动编写所有 OR 映射的代码似乎很糟糕。我认为 nHibernate 将能够帮助进行这种接线,但我正在努力通过所有外键进行映射 - 它们似乎工作正常(订单行产品的外键查找基于外键创建正确的产品对象)直到我尝试进行数据绑定,我无法获取数据绑定的 id 列来更新我的产品或产品类型对象。

我的一般方法是否在正确的范围内?如果是,什么是映射问题的好的解决方案?

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

4

5 回答 5

2

我认为您遇到的问题是,当您绑定到网格时,仅支持 INotifyPropertyChanged 是不够的,但您必须在IBindingList实现中触发 ListChanged 事件,并确保为SupportsChangeNotification覆盖并返回 true财产。如果您不为此返回 true,则网格不会查找它以了解数据是否已更改。

在 .NET 2.0+ 中,您可以使用BindingList类创建一个通用集合,这将解决大部分的麻烦(只是不要忘记为 SupportsChangeNotification 属性覆盖并返回 true)。

如果您用于数据绑定的类具有一个集合属性(例如 IBindingList 或 BindingList),那么您可以将外键网格直接绑定到该属性。在表单设计器中配置绑定时,只需选择集合属性作为网格的数据源。它应该“正常工作”。唯一偷偷摸摸的部分是确保您以正确的方式处理空或空集合。

于 2008-11-11T19:51:11.033 回答
1

欢迎来到 StackOverflow :)

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

ValueMember 是实际控件值的来源(这将是订单行中的键值),显示成员是显示给用户的值而不是值(这将是 FK 值)。

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

于 2008-08-27T07:15:50.937 回答
0

这是一个很好的“我如何”视频,演示了数据绑定:

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

于 2008-08-27T07:46:48.897 回答
0

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

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

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

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

经过大量的探索后,我意识到当我直接设置数据源的“产品类型”属性时,这甚至不起作用,而不是在“产品”设置器中设置它。

我相信让我重回正轨的另一件事是,当我提供一个以主窗体创建的模拟数据访问层时,一切正常。

此外,当我将 nHibernate 制作的 IList 复制到 IBindingList 时 - 一切再次看起来都很好。

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

我将继续研究解决此问题的更好方法,而不是将 IList 复制到 IBindingList - 也许我需要了解线程编组。

编辑

我现在已经开发了一个解决方案来解决这个问题,并认为我理解让我感到困惑的地方——似乎除了基本属性数据绑定之外的任何东西都不能很好地用于不是从 BindingList 派生的列表——只要我试图数据绑定到触发链式 NotifyPropertyChanged 事件的属性,事情变得混乱,我的事件丢失了。

我现在拥有的数据访问解决方案是使用 Rob Conery IRepository模式的变体,将我的集合返回为我创建的自定义类,一个从 BindingList 派生的 SortableBindingLazyList,实现 Sort Core 方法并将其内部列表存储为一个查询,延迟列表实现。

于 2008-09-01T02:27:30.887 回答
0

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

像这样的东西:

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

如果这也适用于您的情况,那将是值得一看的。

于 2008-10-22T09:55:01.537 回答