Downloads
97180.zip

To make the application more useful as a general-purpose demonstration, I added several features that illustrate a few tricky technical points.

Importing pictures. I wanted to show how to insert pictures into the database, so I included a routine to capture the filename of a picture to be imported into the database. Web Listing A shows the routine’s code. I don’t want to discuss the suitability of storing binary large objects (BLOBs) in the database here; suffice it to say that this routine works effectively for importing pictures into SQL Server.

Handing new row initialization. When a user wants to add a new row to the database, it’s a good idea to provide correct default values for the form fields. You can provide the values in a variety of ways, but I used the TableNewRow event handler. In this case, if the user clicks the plus (+) sign in the GetCustomersByStateBindingNavigator, a new row is created behind the scenes and the TableNewRow event is fired, letting you apply whatever logic you want to fill in the new row values. These changes aren’t committed to the database, just to the underlying DataTable. You can find where to add this code by using the TableAdapter Designer. Simply right-click the appropriate TableAdapter diagram and select View Code. You’ll see a blank form where you can add your code to the TableAdapter code. In this case, you’re working with a partial class, which isn’t overwritten when you reconfigure the TableAdapter. The code in Web Listing B implements the TableNewRow event handler for the Customers and Orders tables.

Providing a list of addresses. Because a customer can have several addresses, I provided a drop-down list of addresses in the UI. I implemented the drop-down list by adding another table (Addresses) to the TableAdapter diagram, adding an FK constraint, and disabling the update, delete, and accept/reject rules. I also programmed the SQL Server database to automatically delete all of a customer’s addresses when the customer was deleted.