Flylib.com

Books Software

 
 
 

The Relations Application

Team Fly  

Page 535

The automated discount calculations impose another limitation on the design of the application's interface. The original NWOrders application allows you to switch tabs and select another customer even after adding detail lines to the order. We can't have this flexibility when the discount policy is based on the customer. To prevent users from selecting a new customer after having entered detail lines with discounts for another customer, we disable the Order Header tab. Another approach would be to allow users to select another customer and recalculate the discounts for the detail lines on the Order Detail tab.

The Relations Application

The Relations project demonstrates how to present related data on a Windows form. As you should guess, we're not going to use the DataGrid control, despite the fact that it's been designed to display related tables. The major disadvantage of the DataGrid as a data presentation tool is that it doesn't allow users to view the hierarchy of the data. The DataGrid control displays one level of data at any one time. Besides, users must select the relation they want to view on the control— certainly not the friendliest approach. We must give credit to the designers of the controls for the fact that the DataGrid can display any DataSet. A well-crafted application is very specific as to the data it handles and you can't expect a general tool to accommodate your needs as nicely as a custom solution. And this is what we'll do in this project: we'll write an interface that allows users to select a product from a list and see the customers who purchased the specific product, in how many of their orders it has appeared, and the total number of items of the same product each customer has ordered. The application's form is shown in Figure 18.6.

image

F IGURE 18.6 The Relations project displays sales data about each product.

The Application's Architecture

When the application's form is loaded, all the data are loaded into the ProductSales DataSet. In a real application you should provide an interface that enables users to limit the selection. For example, select orders placed in a time interval, the orders of customers from a specific country, and so on. The tables of the Northwind database are very small and we've chosen to download all their rows to the client.

Team Fly  
Team Fly  

Page 539

The listing is a bit lengthy because it calculates totals, formats the cells of the ListView control, and so on. We'll focus on the statements that navigate through the hierarchy of the DataSet's rows. When the user selects an item in the list, the following actions are performed from within the control's SelectedIndexChanged event handler:

1. The detail lines that refer to the selected product are copied from the Order Details DataTable into an array of DataRow objects with the DataTable's Select method:

DetailRows = _
    ProductSales1.Order_Details.Select(''ProductID = " & productID)

The DetailRows array contains all the rows of the Order Details DataTable that refer to the product whose ID we passed to the Select method as argument.

2. The program creates a new DataTable, the OrdersTable, with the same structure as the original Orders DataTable of the DataSet. This DataTable will store all the rows of the Orders DataTable that correspond to the details selected in step 1. The following statements iterate through the rows of the DetailRows DataTable, retrieve the order to which the detail belongs, and add it to the OrdersTable DataTable. The GetParentRow method accepts as argument the name of the relation between the Order Details and Orders tables.

For Each DetailRow In DetailRows
    OrderRow = DetailRow.GetParentRow("OrdersOrder_Details")
    OrdersTable.Rows.Add(OrderRow.ItemArray)
Next

3. The OrdersTable DataTable now contains the orders that include the product selected on the ListBox control. Another loop iterates through the rows of this DataTable and displays them on the ListView control. In addition, it keeps track of the number of orders placed by each customer and the total amount spent by each customer for the selected product.

4. To retrieve the customer name from each order, the program calls the FindByCustomerID method of the Customers DataTable, passing as argument the customer's ID with the following statements. The CustomerRow variable is of the ProductSales.CustomersRow type.

CustomerID = OrderRow.Item("CustomerID")
CustomerRow = _
          ProductSales1.Customers.FindByCustomerID(CustomerID)

The remaining statements populate the ListView control, calculate the totals, and perform other straightforward tasks .

The Relations project demonstrates an interesting alternative to the DataGrid control for building interfaces that display related data. It involves quite a bit of code, as opposed to the DataGrid, but you have absolute control over the appearance of the data and you can display all the levels of your data hierarchy.

The Relations1 Project

Figure 18.7 shows an application that maps more complicated relations on a ListView control. The Relations1 project maps the publishers of the Pubs database, along with their titles and each title's

Team Fly