9.8. FormView Control: Examining Single Records as Master/DetailAn alternative to the DetailsView control is the FormView control, which is built entirely with templates and, thus, gives you even greater control over the look and feel of the data. DetailsView and FormView are derived from the CompositeDataBoundControl class. Therefore, they share almost all the same properties, as listed in Table 9-8. (The only significant exception is that the FormView does not have an AlternatingRowStyle property.) To demonstrate the FormView , the next exercise will display details from the Products table, and will introduce the idea of navigating to a specific record based on the value chosen by a user from a drop down list of products. Begin by adding a new page called Products to your web site. Drag a DropDownList control from the Toolbox onto the page and give it an ID of ddlProducts . Go to Design view. You'll note that the smart tag opens. Choose New Data Source, and for this exercise, name the new data source NorthWindProductsDataSource . You may use your existing connection, and choose the Product Name (to display) and the product ID (to identify which product was selected), as shown in Figure 9-28. Figure 9-28. Data Source Configuration WizardCheck Enable AutoPostBack in the smart tag or in the Properties window to ensure that when the user makes a selection in the drop down, the page is immediately posted back to the server for processing. You may want to run the application to test that the drop-down is properly filled as it has been in Figure 9-29. Select a product and watch to ensure the page is posted back and that the drop-down is filled with the name of the selected product when the page is redrawn. Figure 9-29. Testing the drop-downWith the DropDownList working, drag a FormView control onto the form. Using the smart tag, create a new data source, this time named NorthWindProductsDetailsDataSource . Select the product details you want to display, as shown in Figure 9-30. Figure 9-30. Configure product data sourceYou want to display product details only for the product chosen by the user. Click the WHERE button to set the parameters for the WHERE clause, which brings up the Add WHERE Clause dialog. Set the column to ProductID and the source to Control. Set the ControlID to the name of the Control , and click Add to add the WHERE clause, as shown in Figure 9-31. Figure 9-31. Adding drop-down WHERE clauseYou'll want the control to support inserting and deleting records, as well as updating records. Click the Advanced button and check "Generate Insert, Update and Delete statements," then click OK. Unlike the DetailsView , the FormControl 's display is entirely controlled by templates that you can modify using standard ASP.NET and HTML controls. Before editing the templates, edit the page to type in the header: Form View Display, and set it to heading level 1. <h1> Form View Display</h1> Next, open the smart tag (or right-click on the control) and choose Edit Templates. The first template to edit is the ItemTemplate . You can click on the template box and grab the resizing handles to make it wider and taller. Click in the top of the Item template, and hit enter a few times to make some room. Then type a heading such as Product Details. Select the title and set it to Heading 2 using the Toolbar, as shown in Figure 9-32. Figure 9-32. Setting the Item template headingPreviously, you laid out the controls in a template by stacking them. Most web designers will use tables to control layout, and you can do so from within the template. Click the menu choice Layout Insert Table. In the Insert table dialog, set the Custom Layout to 5 rows (one for each of ProductID, ProductName, UnitPrice, Units in Stock, and the Edit/Delete/New buttons ), and set two columns (one for display and one for the label). Set the cell width to 50 pixels and the cell height to 30 pixels, as shown in Figure 9-33. Figure 9-33. Insert Table dialog boxTo set the prompt for the ProductID , type ID into the upper-left cell. Then click and drag the ProductIDLabel control into the upper- righthand cell. Your first row is now laid out with precision. Similarly, drag the ProductNameLabel control into the second row's righthand cell, and put a prompt (Product:) in the cell to its left. Do the same with the two remaining label controls. To right-align the prompts, click to highlight the left column, and set the Align property in the properties window. Expand the righthand column (highlight and then drag the column) to make room for large product names , as shown in Figure 9-34. Figure 9-34. Editing the Product Item templateWhen the template is set the way you want, click on the smart tag and choose End Editing Templates. Examine the source. Everything you've done with wizards is reflected here, and you can edit the source directly: <asp:FormView runat="server" ID="FormView1" DataSourceID="NorthWindProductsDetailsDataSource" DataKeyNames="ProductID" Width="410px"> Within the FormView (between the opening tag shown above, and the closing tag much later in the file), you'll find a series of ItemTemplates . The first dictates how the item should look when you first see it (not editing): <ItemTemplate> <h2>Product Details</h2> <table> <tr> <td style="width: 120px" align="right"> ID: </td> <td style="width: 391px"> <asp:Label ID="ProductIDLabel" runat="server" Text='<%# Eval("ProductID") %>' /> </td> </tr> <tr> <td style="width: 120px" align="right"> Product: </td> <td style="width: 391px"> <asp:Label ID="ProductNameLabel" runat="server" Text='<%# Bind("ProductName") %>' /> </td> </tr> <tr> <td style="width: 120px" align="right"> Price: </td> <td style="width: 391px"> <asp:Label ID="UnitPriceLabel" runat="server" Text='<%# Bind("UnitPrice") %>' /> </td> </tr> <tr> <td style="width: 120px; height: 40px" align="right"> Units in stock: </td> <td style="width: 391px; height: 40px"> <asp:Label ID="UnitsInStockLabel" runat="server" Text='<%# Bind("UnitsInStock") %>' /> </td> </tr> <tr> <td style="width: 120px; height: 21px" align="right"> </td> <td style="width: 391px; height: 21px"> <asp:LinkButton ID="NewButton" runat="server" Text="New" CommandName="New" /> <asp:LinkButton ID="EditButton" runat="server" Text="Edit" CommandName="Edit" /> <asp:LinkButton ID="DeleteButton" runat="server" Text="Delete" CommandName="Delete" /> </td> </tr> </table> </ItemTemplate> Run the application to see how the items look. They should resemble Figure 9-35. Figure 9-35. Testing the Form View display9.8.1. Editing with FormViewThe FormView includes links to create new records, edit existing records, or delete records. When you click Edit, the FormView automatically enters edit mode (you do not have to write code to make this happen) and switches to its EditItem template. You want that EditItem template to present the data using, for example, text box controls. The ProductIDLabel control is not editable, so drag this into the header so your page will inform the user which record is being edited. Next, recreate the table from the previous template into the EditItems template, but use text boxes where you previously used labels: <EditItemTemplate> <h2> Product Detail - Editing <asp:Label Text='<%# Eval("ProductID") %>' runat="server" ID="ProductIDLabel1" /> </h2> <br /> <table style="width: 273px"> <tr> <td style="width: 100px" align="right"> Name:</td> <td style="width: 543px"> <asp:TextBox ID="ProductNameTextBox" runat="server" Text='<%# Bind("ProductName") %>' Width="271px" /> </td> </tr> <tr> <td style="width: 100px" align="right"> Price:</td> <td style="width: 543px"> <asp:TextBox ID="UnitPriceTextBox" runat="server" Text='<%# Bind("UnitPrice") %>' Width="75px" /> </td> </tr> <tr> <td style="width: 100px" align="right"> Units in stock:</td> <td style="width: 543px"> <asp:TextBox ID="UnitsInStockTextBox" runat="server" Text='<%# Bind("UnitsInStock") %>' Width="76px" /> </td> </tr> <tr> <td style="width: 100px" align="right"> <asp:LinkButton ID="UpdateButton" runat="server" Text="Update" CommandName="Update" /> </td> <td style="width: 543px"> <asp:LinkButton ID="UpdateCancelButton" runat="server" Text="Cancel" CommandName="Cancel"/> </td> </tr> </table> </EditItemTemplate> The result is shown in Figure 9-36. Figure 9-36. Edit Item templateRun the program and use the drop-down to pick a product (e.g., Laughing Lumberjack Lager). Click Edit and the Edit window (based on the EditItem template) opens. You are free to enter new values, as shown in Figure 9-37. Figure 9-37. Testing editingThe Header shows the product ID. Change the values and click Update. You are returned to the updated display page showing the new values. You can check that the database was updated, as shown in Figure 9-38. Figure 9-38. Updated product in DB9.8.2. Inserting New RecordsJust as clicking Edit in the FormView put you in edit mode and used the EditItem template, clicking New puts you in Insert mode and uses the InsertItem template. Rather than recreating the same work, copy and paste the EditItem template to the InsertItem template, being sure to fix the header and the names of the controls. The result is shown in Figure 9-39. Figure 9-39. Insert Item template9.8.3. DetailsView and FormView EventsBoth the DetailsView and FormView controls can raise events in response to a large number of user interactions, such as inserting, updating, or deleting items. A list of the most commonly used events is contained in Table 9-9. A common scenario for using these events follows . Table 9-9. DetailsView and FormView events
When you change the name of a product or add a new product, you want those changes reflected in the drop-down. To accomplish this, you'll want to update the DropDownList control after each edit. To do this, you'll handle the ItemInserted and the ItemUpdated events of the FormView to rebind the drop-down list with the new data: protected void FormView1_ItemInserted( object sender, FormViewInsertedEventArgs e ) { ddlProducts.DataBind( ); } protected void FormView1_ItemUpdated( object sender, FormViewUpdatedEventArgs e ) { ddlProducts.DataBind( ); } To test this, navigate to Ipoh Coffee and click Edit. In the name field, enter the name of your favorite coffee (being from the Boston area, mine is Green Mountain). While you are at it, drop the price from $46 (only people in Seattle pay that much for coffee) down to a somewhat more reasonable $9.00. Click Update. Ipoh Coffee is no longer in the drop-down, but Green Mountain is as shown in Figure 9-40. Figure 9-40. Drop-down list updated |