Figure 11-27. DataList bound to SQL data control


11.3. The DataList Control

The toolbox provides a DataList control for creating templated lists of data. A templated list is one in which you control the HTML used to render the list by defining templates: each template describes how to display one item in the list.

DataList controls provide fairly simple templates; if you need very precise control of the layout, consider using the Repeater control.


To get started create a new web site called webNorthWindDataControls and copy the web site named WebNorthWind. Add a web form to your application named DataControls. Right-click on DataControls.aspx in the Solution explorer, and make it the start page for your application.

Switch to Design view and drag a DataList control onto Datacontrols.aspx. Notice that the smart tag opens, offering you an opportunity to choose a data source. Choose New Data Source and for this exercise, choose SQL Database, naming the new data source DataListCustomerDataSources. Use your existing connection to Northwind, and specify that you want all the fields in the Customers table. When you finish, the DataList is populated with labels that represent the field names, and labels that are bound to the data control, as shown in Figure 11-27.


If you click on Source, you will see that the DataList has been defined with a number of attributes to identify its data source, as shown in Example 11-8.

Example 11-8. DataList control source
 <asp:DataList runat="server" DataKeyField="CustomerID" DataSource> 

Between the opening and closing tags of the DataList is an ItemTemplate tag that defines how each item will be displayed.

Click on the DataList's smart tag and choose Edit Templates. The ItemTemplate (the default) is opened, as shown in Figure 11-28.

Each column is represented as text, and the bound value is represented by a label. Click End Template Editing and examine the source produced. The label is populated using the Eval method on a column from the underlying data, as shown in Example 11-9.

Figure 11-28. ItemTemplate editor


Example 11-9. Label control source
 <asp:Label     Text='<%# Eval("CustomerID") %>'     runat="server"     > </asp:Label> 

Eval returns the value of the underlying data in the column whose name is passed in as a string.


There are a number of ways to improve the look and feel of this control. First, you can return to Design view, and click the Auto Format... link to choose a scheme (e.g., Classic). Doing so adds a number of styles to the DataList (after the opening tag but before the ItemTemplate tag).

     <FooterStyle ForeColor="White" Font-Bold="True" BackColor="#507CD1" />     <SelectedItemStyle ForeColor="#333333" Font-Bold="True" BackColor="#D1DDF1" />     <AlternatingItemStyle BackColor="White" />     <ItemStyle BackColor="#EFF3FB" />     <HeaderStyle ForeColor="White" Font-Bold="True" BackColor="#507CD1" /> 

Once again you may return to the smart tag, and again choose Edit Templates. You are returned to Template Editing Mode (which continues until you click the link End Template Editing), and you may edit the layout of the template in any way you choose. Notice that there are different templates for Items, SelectedItems, and EditItems so that you can display data as labels in Item mode, but as (for example) text boxes or drop-down lists in Edit mode, as shown in Figure 11-29. You can hand populate the EditItemTemplate (dragging in labels, text boxes, and drop-down lists) or, you can create the EditItemTemplate by ending Template editing and switching to Source view.

Figure 11-29. EditItem template


Copy the entire <ItemTemplate> section and in the copy, change the name from ItemTemplate to EditItemTemplate. Now modify the contents of the template by changing labels to text boxes. You can switch back and forth between editing in Source view and editing in the template Design view.

11.3.1. Organizing the Flow of the DataList

By default, each item is displayed below the next, in a vertical column. You may modify this by setting the RepeatDirection property of the DataList from Vertical to Horizontal and by setting the number of columns by setting the RepeatColumns property, as shown in Figure 11-30.

11.3.2. Editing Items in List Controls

To switch to the EditItemTemplate, you'll want a way to enter and to exit editing once the user has made changes. The easiest way is to drag buttons directly into the template form. For example, you might drag two buttons onto the ItemTemplate form. Set the ID for the first to ItemEditButton and for the second to ItemDeleteButton. Set the Text property appropriately (e.g., Edit and Delete), but be sure to set the CommandName property carefully. The Edit button's CommandName must be set to edit (case sensitive), and the Delete button's CommandName property must be set to delete. Setting the CommandName properly will cause the appropriate event to fire (e.g., the EditCommand event) for which you can create handlers (CancelCommand, EditCommand, UpdateCommand, DeleteCommand).

The easiest way to create the EditCommand, UpdateCommand, DeleteCommand, and CancelCommand event handlers is from Design view. Click on the DataList control; in

Figure 11-30. DataList column layout


the Properties window click on the lightning bolt to bring up the list of events, and you'll find the various commands. You can double-click as usual to have Visual Studio 2005 help you set up the event handlers.

The edit command and the delete command event handlers both receive a DataListCommandEventArgs object as their second parameter. The DataListCommand-EventArgs contains an Item property, representing the list item the user wants to edit (or delete). The DataListItem returned by the Item property, in turn, has an ItemIndex property, which, in the case of editing, you'll assign to the EditItemIndex property of the DataList. You'll then rebind the DataList. These changes are shown in Example 11-10.

Example 11-10. Edit command event handler
 Protected Sub DataList1_EditCommand( _ ByVal source As Object, _ ByVal e As System.Web.UI.WebControls.DataListCommandEventArgs) _ Handles DataList1.EditCommand     DataList1.EditItemIndex = e.Item.ItemIndex     DataBind( ) End Sub 

As you can see, it sounds harder than it is!

When you switch to Edit view, you'll want to have both a Save and a Cancel button. You'll need to add those buttons to the EditItemTemplate, either in Source view, as shown in Example 11-11 or by switching to Design view and dragging buttons into the EditItemTemplate.

Example 11-11. Save and Cancel button source
 <asp:Button          Text="Save"     runat="server"     CommandName="Update" /> <asp:Button          Text="Cancel"     runat="server"     CommandName="Cancel" /> 

Notice the CommandName properties. These must be set to Update and Cancel (initial cap), respectively. Switch to Design view and click on the DataList itself. In the Properties window, click on the lightning bolt and you'll find both a CancelCommand and an UpdateCommand. Double-clicking on the space for the command name will create default command names and the skeletons for the event handlers. For example, you might implement the Cancel command, as shown in Example 11-12.

Example 11-12. Cancel command event handler
 Protected Sub DataList1_CancelCommand( _ ByVal source As Object, _ ByVal e As System.Web.UI.WebControls.DataListCommandEventArgs) _ Handles DataList1.CancelCommand     DataList1.EditItemIndex = -1     DataBind( ) End Sub 

The code to implement the Update command will be more complex, requiring that you read through the controls and update the appropriate fields in the database. For now, you can stub it out with the same code you use in the Cancel command.

Run the application and click the Edit button. You'll see the selected item switch to your EditItemTemplate view, as shown in Figure 11-31.

You can, of course, use other kinds of controls besides text boxes. For example, for some data items, a set of radio buttons or a checkbox might be a more appropriate choice. If you wish to control the data entry, you might use a drop-down list that is, itself, bound to data (perhaps from another table in the database).

11.3.3. Deleting Items from a List Control

To allow your user to delete a record, let's return to the Delete button you added to the ItemTemplate.

Figure 11-31. DataList in Edit mode


You'll need to drag another DataSource control onto the page to handle the Delete command (name it DataListCustomerDeleteDataSource). Con the DataSource as you have previously, setting it up to select all the fields of the Customers table.

Next, set the Delete command by clicking on the DeleteQuery property, as shown in Figure 11-32.

Clicking the ellipsis shown in Figure 11-32 opens the Command and Parameter Editor in Figure 11-33.

Enter the Delete command:

     Delete from Customers where CustomerID = @CustomerID 

Click the Add Parameter button to add the parameter you'll need for the Delete command. Rename the parameter CustomerID and set its Parameter source to None and its Default Value to blank, as shown in Figure 11-33.

The complete source code for your new SQLDataSource object should look like Example 11-13.

Figure 11-32. Creating the Delete query


Figure 11-33. Command and Parameter Editor


Example 11-13. SQLDataSource source code
 <asp:SqlDataSource runat="server" ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>" SelectCommand="Select * from Customers" DeleteCommand="Delete from Customers where CustomerID = @CustomerID">     <DeleteParameters>         <asp:Parameter Name="CustomerID" />     </DeleteParameters> </asp:SqlDataSource> 

Make sure you set the DataKeyField property of the DataList control to the primary key of the table you'll be deleting records from (it should already be set to CustomerID).


Create your event handler for the DeleteCommand event, just as you created a handler for the Edit event. The steps are:

  1. Get the record ID from the selected record (the one whose Delete button was pushed).

  2. Get the parameter from the Parameters collection of the new DataSource object.

  3. Set the parameter's DefaultValue to the record ID of the record to be deleted.

  4. Call Delete on the DataSource.

  5. Rebind the DataList.

These steps are shown in Example 11-14.

Example 11-14. Deleting a record from a DataList
 Protected Sub DataList1_DeleteCommand( _  ByVal source As Object, _  ByVal e As System.Web.UI.WebControls.DataListCommandEventArgs) _  Handles DataList1.DeleteCommand      ' (1) Get the recordID from the selected item (a string)      Dim recordID As String = _          DataList1.DataKeys.Item(e.Item.ItemIndex).ToString( )      ' (2) Get a reference to the CustomerID parameter      Dim param As System.Web.UI.WebControls.Parameter = _          DataListCustomerDeleteDataSource.DeleteParameters("CustomerID")      ' (3) Set the parameter's default value to the value for      ' the record to delete      param.DefaultValue = recordID      ' (4) Delete the record      DataListCustomerDeleteDataSource.Delete( )      ' (5) Rebind the list      DataBind( )  End Sub 

The first line is a bit tricky; let's break this out into a number of substeps to make it easier to understand:

     Dim recordID As String = _         DataList1.DataKeys.Item(e.Item.ItemIndex).ToString( ) 

You are given a DataListCommandEventArgs object (e) as a parameter. That DataListCommandEventArgs instance has an Item property of type DataListItem, which you can assign to a variable theItem.

     ' get the Item property from the parameter     Dim theItem As DataListItem = e.Item 

You can ask that DataListItem for its ItemIndex (the index into the list for the selected item):

     ' get the itemIndex from the Item     Dim itemIndex As Integer = theItem.ItemIndex 

Next, you can ask the DataList for its collection of DataKeys. Remember that you set the DataKeyField attribute of the list:

     <asp:DataList        DataKeyField="CustomerID" 

so this collection contains all the CustomerIDs, one for each row:

     ' Get the DataKeys collection from the Data List     Dim keyCollection As DataKeyCollection = DataList1.DataKeys 

With a reference to that collection and the index, you can extract the contents of the key collection at that index. Remember that what you get back is of type Object:

     ' Get the object stored at the ItemIndex inside the collection     Dim theRecordAsObject As Object = keyCollection(itemIndex) 

You know that what you have is a string, so you can cast that returned object to string:

     ' Cast the result from object to string     Dim recordID As String = theRecordAsObject.ToString( ) 

All of this work is combined in the first line of the method:

     Dim recordID As String = _         DataList1.DataKeys.Item(e.Item.ItemIndex).ToString( ) 

The second line asks the DataListCustomerDeleteDataSource to index into its DeleteParameters for the parameter whose name is CustomerID and return a reference to that parameter:

     Dim param As System.Web.UI.WebControls.Parameter = _         DataListCustomerDeleteDataSource.DeleteParameters("CustomerID") 

You can also search using an ordinal, so you could rewrite this line as:

     Dim param As System.Web.UI.WebControls.Parameter = _         DataListCustomerDeleteDataSource.DeleteParameters(0) 

Using the name of the parameter is clearer, however.

The third line sets the DefaultValue property of this parameter to the recordID you extracted earlier, the fourth line calls the Delete method on the DataSource and the final line rebinds the control, now missing the record you've deleted.

11.3.4. Trying It Out

If you try this, however, it will almost certainly fail. The problem is that almost all the customer records have orders associated with them, and the Northwind database is set up to prevent deleting any customer who has associated orders (a good practice, to avoid data corruption).

You can work around this by creating a new customer, as shown in Figure 11-34.

Figure 11-34. Creating a dummy record


Once this record is added, place a break point on the first line of your new event handler (DataList1_DeleteCommand) and run the application. Scroll down to the new record you've added and click the Delete button, as shown in Figure 11-35.

Figure 11-35. Deleting the record


Once the button is clicked, your application will stop at the break point you've set. As you step through, you can see that the record ID retrieved matches the record that you've asked to delete, and once the method completes, you can scroll down and see that the record has, in fact, been deleted (which you can also verify directly in the database).

11.3.5. Examining One Record at a Time: The DetailsView

Another way to look at your data is one record at a time. The Toolbox offers a control explicitly for this purpose: the DetailsView. Create a new page in your application (DetailsView.aspx) and drag a DetailsView object onto the page. Make DetailsView.aspx your new start page.

The smart tag will open and will offer you the opportunity to create a new DataSource. Call this one CustomersDetailsViewDataSource, and set it to get all the records in the Customers table. Use the Autoformat... smart tag menu choice on the DetailsView control to pick a nice color scheme, check the Enable Paging checkbox so that you can page through the records, and run the application.

It is easy to customize the UI for this control, using style properties (e.g., HeaderStyle, RowStyle, etc.) as well as by using templates.

In addition, you can set the AutoGenerateEditButton property to TRue, and the control will automatically render an Edit button.

Build and run the application. When you press the Edit button, the control enters Edit mode, and the currentMode property changes from ReadOnly to Edit. Each field of the control is rendered in its Edit User interface (which can be customized using styles and templates), as shown in Figure 11-36.

Figure 11-36. Detail view Editing mode


Notice that the edit text boxes were created for you automatically, as were the links for Update and Cancel. If you set the DataSource to create the Update and Delete commands (using the Advanced button in the configuration dialogs), the Update link works with no additional code. In addition, the wizard also generates the code to create the Insert and Delete buttons, as shown in the attributes of the DetailsView in Example 11-15.

Example 11-15. DetailsView control source
 <asp:DetailsView runat="server" Height="50px" Width="125px" DataSource AutoGenerateRows="False" DataKeyNames="CustomerID" ForeColor="#333333" GridLines="None" CellPadding="4" AllowPaging="True" AutoGenerateEditButton="True" AutoGenerateDeleteButton="True" AutoGenerateInsertButton="True">     <FooterStyle ForeColor="White" Font-Bold="True" BackColor="#990000" />     <CommandRowStyle Font-Bold="True" BackColor="#FFFFC0" />     <RowStyle ForeColor="#333333" BackColor="#FFFBD6" />     <PagerStyle ForeColor="#333333" HorizontalAlign="Center"     BackColor="#FFCC66" />     <Fields>         <asp:BoundField ReadOnly="True" HeaderText="CustomerID"         DataField="CustomerID" SortExpression="CustomerID"/>         <asp:BoundField HeaderText="CompanyName"         DataField="CompanyName" SortExpression="CompanyName"/>         <asp:BoundField HeaderText="ContactName"         DataField="ContactName" SortExpression="ContactName"/>         <asp:BoundField HeaderText="ContactTitle"         DataField="ContactTitle" SortExpression="ContactTitle"/>         <asp:BoundField HeaderText="Address"         DataField="Address" SortExpression="Address" />         <asp:BoundField HeaderText="City"         DataField="City" SortExpression="City" />         <asp:BoundField HeaderText="Region"         DataField="Region" SortExpression="Region" />         <asp:BoundField HeaderText="PostalCode"         DataField="PostalCode" SortExpression="PostalCode" />         <asp:BoundField HeaderText="Country"         DataField="Country" SortExpression="Country" />         <asp:BoundField HeaderText="Phone"         DataField="Phone" SortExpression="Phone" />         <asp:BoundField HeaderText="Fax"         DataField="Fax" SortExpression="Fax" />     </Fields>     <FieldHeaderStyle Font-Bold="True" />     <HeaderStyle ForeColor="White" Font-Bold="True" BackColor="#990000" />     <AlternatingRowStyle BackColor="White" /> </asp:DetailsView> 

11.3.6. Examining Single Records with FormView (Master/Detail)

An alternative to the DetailsView is the FormView, which is built entirely with templates and, thus, gives you even greater control over the look and feel of the data. To demonstrate this, the next exercise will display details from the Products table, and will navigate to a specific record based on a value chosen by the user from a drop-down list of products.

Begin by creating a new page. Call it Products and make it your new start page.

Drag a drop-down list control from the Toolbox onto the form. Set its ID to ddlProducts. You'll note that the smart tag opens. Choose New Data Source, and for this exercise, name the new DataSource 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 11-37.

Figure 11-37. Data Source Configuration wizard


Don't forget to click AutoPostBack in the smart tag or in the Properties window to ensure that when the user makes a selection in the drop-down list, the page is posted back to the server for processing. You may want to run the application to test that the drop-down list is properly filled, as shown in Figure 11-38. Select a product, then watch to make sure the page is posted back and that the drop-down list is filled with the name of the selected product when the page is redrawn.

With the drop-down list working, you are now ready to drag a Form View control onto the form. Using the Form View's smart tag, create a new data source, this time named NorthWindProductsDetailsDataSource. Select the product details, as shown in Figure 11-39.

Figure 11-38. Testing the drop-down list


Figure 11-39. Configure Products data source


You 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. This brings up the Add Where Clause button. Set the column to ProductID and the Source to control. Set the ControlID to the name of the drop-down list (ddlProducts), and click Add to add the Where clause, as shown in Figure 11-40.

Click OK.

You'll want the control to support inserting and deleting records, as well as updating records. Click the Advanced button and Generate Insert, Update, and Delete statements, then click OK.

Finally, click Next and Finish to complete the configuration of the DataSource.

Figure 11-40. Adding drop-down list Where clause


Unlike the DetailsView, the FormView's display is entirely controlled by templates that you can modify using standard ASP.NET and HTML controls. Before editing the templates, switch to Source view and edit the page to type in a header just below the opening <div> tag: Product View Display, and set it to Heading 1.

     <h1> Product 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 itself 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 11-41.

Previously, you laid out the controls in a template by stacking them one over the other. Most web designers will use tables to control layout, and you can do so from within the template itself.

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 11-42.

Click OK.

To set the prompt for the productID just 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.

Figure 11-41. Setting the Product view ItemTemplate heading


Figure 11-42. Insert Table dialog


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 then set the Align property in the Properties window. Be sure to expand the righthand column (highlight and then drag the column) to make room for large product names, as shown in Figure 11-43.

Figure 11-43. Editing the Product Item template


When the template is set the way you want, click on the smart tag and choose End Editing Templates.

Examine the source in Example 11-16. Everything you've done with wizards is reflected here, and you can, of course, edit the source directly.

Example 11-16. FormView control source
 <asp:FormView runat="server" DataSource DataKeyNames="ProductID" Width="410px"> 

Within the FormView (between the opening tag shown earlier, and the closing tag much later in the file) you'll find a series of ItemTemplate s. The first dictates how the item should look when you first see it (not editing, etc.), as shown in Example 11-17.

Example 11-17. ItemTemplate source
 <ItemTemplate>     <h2>Product Details</h2>     <table>         <tr>             <td style="width: 120px" align="right">                 ID:             </td>             <td style="width: 391px">                 <asp:Label  runat="server"                 Text='<%# Eval("ProductID") %>' />             </td>         </tr>         <tr>             <td style="width: 120px" align="right">                 Product:             </td>             <td style="width: 391px">                 <asp:Label  runat="server"                 Text='<%# Bind("ProductName") %>' />             </td>         </tr>         <tr>             <td style="width: 120px" align="right">                 Price:             </td>             <td style="width: 391px">                 <asp:Label  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  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                  runat="server" Text="New"                 CommandName="New" />                 <asp:LinkButton                  runat="server" Text="Edit"                 CommandName="Edit" />                 <asp:LinkButton                  runat="server" Text="Delete"                 CommandName="Delete" />             </td>         </tr>     </table> </ItemTemplate> 

Run the application to see how the items look. They should resemble what's shown in Figure 11-44.

Notice that the FormView includes links to create new records, edit records, or delete records. When you click Edit, the FormView will automatically enter Edit mode (you do not have to write code to make this happen), as shown in Figure 11-45. I've changed item 43 to my favorite coffee and set its price at something a bit more reasonable.

Figure 11-44. Testing the FormView display


You can check that the database was properly updated by returning to Visual Studio 2005, opening the database, and examining the products table, as shown in Figure 11-46.

11.3.7. Inserting New Records

Just as clicking Edit in the FormView put you in Edit mode and used the EditItems template, clicking New puts you in Insert mode, and uses the InsertItems template to insert items into the database.

11.3.8. Updating the Drop-Down List

When you change the name of a product, or add a new product, you want those changes reflected in the drop-down list. So you'll want to update the drop-down control after each edit. To do so, you'll handle the ItemInserted and the ItemUpdated events of the FormView to rebind the drop-down list with the new data, as shown in Example 11-18.

Figure 11-45. Updating the Product view


Figure 11-46. Checking the update in the database


Example 11-18. ItemInserted and ItemUpdated event handlers
 Protected Sub FormView1_ItemInserted( _ ByVal sender As Object, _ ByVal e As System.Web.UI.WebControls.FormViewInsertedEventArgs) _ Handles FormView1.ItemInserted     ddlProducts.DataBind( ) End Sub Protected Sub FormView1_ItemUpdated( _ ByVal sender As Object, _ ByVal e As System.Web.UI.WebControls.FormViewUpdatedEventArgs) _ Handles FormView1.ItemUpdated     ddlProducts.DataBind( ) End Sub 

To test this, edit Green Mountain Coffee again (set its name to Green Mountain French Roast) and click Update. Notice that Green Mountain Coffee is no longer in the drop-down list, but Green Mountain French Roast is, as shown in Figure 11-47.

Figure 11-47. Drop-down menu updated




Programming Visual Basic 2005
Programming Visual Basic 2005
ISBN: 0596009496
EAN: 2147483647
Year: 2006
Pages: 162
Authors: Jesse Liberty

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net