Hierarchical TableAdapters 301
Tuning and Augmenting the Generated Code
Now comes the fun part—at least it separates the kids from the grownups when it comes to skill. Although Visual Studio has generated code to support some of the drag-and-drop operations, there are a number of missing links and blocks of code that you'll need to add to get the project to work as expected. That's partly due to the use of stored procedures and the fact that you deleted two of the FillToolStrip controls. Walk through the application on a function basis to see where you need to fill in the blanks.
Implementing the Fill Button
The FillToolStrip control captures the two input parameters (StateWanted and Name Hint) and exposes a button that the user can press to populate the list of customers. As implemented, the FillToolStripButton_Click event executes the GetCustomersByStateTableAdapter.Fill method—passing in the parameters from the FillToolStrip TextBox controls. Unfortunately, this does not automatically populate the child rowsets, so it's necessary to call the orders and items Fill methods as well. Each of these methods are focused queries that only return orders for a specific customer and only items from a particular customer order. You also need to add an exception handler to deal with the case when there are no customers within the given range. To make sure the user does not try to add rows before the initial rowset population, I disabled the BindingNavigator and re-enabled it when the query returned at least one row. The code for this routine is shown in Figure 9.
Click here for a larger image.
Figure 9: The FillToolStripButton_Click event handler.
Handling Rowset Population for the Child DataTables
When the user chooses a specific customer to view and when the list of customers is initially populated, you need to populate the lists of applicable child orders and items. This process is handled in two event handlers that trigger off the BindingSource PositionChanged event. These events fire when the user chooses another customer or another order for a specific customer. In each of these routines, I call the appropriate TableAdapter Fill method—passing in the current customer ID and order ID to focus the query on just the rows related to this customer. The code is shown in Figure 10.
Figure 10: Handling the PositionChanged events to populate child rowsets.
Page 4 of 5