关于c#:WinForms数据绑定和外键关系

关于c#:WinForms数据绑定和外键关系

WinForms databinding and foreign key relationships

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

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

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

用户可以直接向网格添加或编辑订单行,并从comboBoxColumn中选择订单行的产品-然后,这应更新producttype列,并在同一行中显示所选产品的产品类型。

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

这适用于数据绑定方面,但是必须手动对存储库中所有OR映射进行编码。我以为nHibernate可以帮助完成此连接,但是正在努力处理所有外键的映射-它们似乎可以正常工作(对订单行产品的外键查询会根据外键创建正确的产品对象),直到我尝试进行数据绑定,我无法获取数据绑定的ID列来更新我的产品或产品类型对象。

即使在正确的球场上,我的一般方法也可以吗?如果是,那么映射问题的一个好的解决方案是什么?

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


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

在.NET 2.0+中,您可以使用BindingList类创建一个通用集合,这将处理大多数麻烦事(只是不要忘记重写并为SupportsChangeNotification属性返回true)。

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


欢迎来到StackOverflow :)

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

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

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


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

像这样:

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

值得一看,这是否也适用于您的情况。


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

问题不在于数据绑定到DataGridView的一般性问题,也不在于DataGridViewComboBoxColumn的实现-正如回答正确的人所说的那样,这在Web上已得到很好的记录。

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

在我的订单示例中,当我更改"产品"(Product)列的值时,"产品类型"(Product Type)列并未更新-即使在代码中我正在设置属性并触发NotifyPropertyChanged事件。 (在调试中,我转到所有正确的位置)

反复研究之后,我意识到当直接设置数据源的" Product Type"属性时,甚至在" Product"设置器中进行设置时,这甚至都无法正常工作。

我相信让我回到正确的轨道上的另一件事是,当我提供以主窗体创建的模拟数据处理层时,一切正常。

另外,当我将nHibernate制作的IList复制到IBindingList时-一切都很好。

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

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

编辑

我现在已经开发出一种解决方案,可以解决该问题,并认为我理解使我感到困惑的问题-似乎,除了基本属性数据绑定之外,对于不从BindingList派生的列表来说,它都不能很好地发挥作用。将数据绑定到引发链式NotifyPropertyChanged事件的属性,事情变得一团糟,我的事件迷路了。

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


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

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


推荐阅读