Binding WinForms Data and Foreign Keys

I am developing a WinForms application (.Net 3.5, without WPF) where I want to be able to display foreign key requests in a DataGridView of data.

An example of this relationship is that I have an OrderLines table. For custom lines, the relationship of foreign keys to Products and Products, in turn, has a relationship of foreign keys to ProductTypes.

I would like to have a database-bound DataBridView, where each row is an ordered line showing the linear product and type of product.

Users can add or edit order lines directly to the grid and select a product for the order line from comboBoxColumn - this should then update the producttype column, showing the product type for the selected product, on the same line.

The closest to a good fit I have found so far is to introduce a domain object representing an ordered line, and then bind the DataGridView to a collection of these order lines. Then I add properties to the ordering object, which expose the product and product type, and raise relevant notifypropertychanged events to keep everything up to date. In my orderline repository, I can connect mappings between this ordering object and three tables in my database.

This works on the data binding side, but you need to pass the code to everyone that OR-mapping in the repository seems bad. I thought nHibernate would be able to help with this connection, but I am struggling with comparisons on all foreign keys - they seem to work fine (finding a foreign key for an orderline product creates the correct product object based on the foreign key) while I try to bind the data I cannot get columns of data identifiers for updating product or product objects.

Is my overall approach even in the right chalet? If so, what is a good solution to the mapping problem?

Or, is there a better solution for binding data rows, including finding a foreign key that I haven't even considered?

+6
c # winforms
source share
5 answers

I think the problem you are facing is that when you snap to the grid, it is not enough to support INotifyPropertyChanged, but you should fire ListChanged events on the IBindingList and make sure you override and return true for the SupportsChangeNotification property. If you do not return true for this, the grid will not search to see if the data has changed.

In .NET 2.0+, you can create a shared collection using the class

+2
source share

Welcome to StackOverflow :)

Usually what you would do is the basic information in the drop-down list for the two values ValueMember and DisplayMember .

ValueMember is the source of the actual control value (this will be the key value in the order line), the display element is the value that is displayed to the user instead of the value (this will be the FK value).

Is there any specific reason why you cannot just return all the necessary data and set these properties?

+1
source share

Here's a good How-To video demonstrating data binding:

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

0
source share

My initial question was obviously not clear, sorry for that.

The problem was not related to data binding to the DataGridView as a whole or to the implementation of the DataGridViewComboBoxColumn - as people have already correctly said, this is well documented on the Internet.

The problem I was trying to solve is updating properties that are detailed through relationships.

In my order example, when I change the value of the Product column, the Product Type column is not updated - even if in the code I set the property and fire the NotifyPropertyChanged event. (In debugging, I go to all the right places)

After much thought, I realized that this did not even work when I directly set the "Product Type" property of the data source, and did not set it in the "Product" installer.

Another thing that seems to me to get me back on the right track is that when I provide a simulated data access layer created in the main form, everything works fine.

Also, when I copy the IList created by nHibernate to the IBindingList, everything looks fine again.

So the problem, I think, is related to thread loss and NotifyPropertyChanged events that get lost when using certain data sources in a certain way (I would like to be more specific than that!)

I'm going to continue to explore better ways to solve this problem than copying IList to an IBindingList - maybe I need to know about thread allocation.

edit

Now I have developed a solution that solves the problem and I think I understand what bothers me - it seems that something other than binding the data of the basic property is not very suitable for lists that are not derived from the BindingList - as soon as I tried When binding data to properties that triggered NotifyPropertyChanged events, everything went awry and my events got lost.

I now have a data access solution using a Rob Conery IRepository template option that returns my collections for binding in the form of a custom class I created, SortableBindingLazyList, a derivative of BindingList, implements Sort Core methods, and also stores its internal list as a request that delays materialization of the list.

0
source share

Well, I don’t know if this is supported by DataGridView, but when you do regular WinForms binding (say to regular TextBox), you can use property paths to move around the relation object.

Something like that:

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

It would be helpful to see if this works in your situation.

0
source share

All Articles