The DataList control, like the Repeater control, is template driven. Unlike the Repeater control, by default, the DataList renders an HTML table. Because the DataList uses a particular layout to render its content, you are provided with more formatting options when using the DataList control. In this section, you learn how to use the DataList control to display data. You also learn how to render database records in both single-column and multi-column HTML tables. We also explore how you can edit data with the DataList control. Displaying Data with the DataList Control To display data with the DataList control, you must supply the control with an ItemTemplate. The contents of the ItemTemplate are rendered for each data item from the data source. For example, the page in Listing 13.6 uses a DataList to display the contents of the Movies database table. The ItemTemplate displays the values of the Title, Director, and BoxOfficeTotals columns (see Figure 13.5). Figure 13.5. Displaying database records with the DataList control. Listing 13.6. ShowDataList.aspx <%@ Page Language="VB" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>Show DataList</title> </head> <body> <form runat="server"> <div> <asp:DataList DataSource Runat="server"> <ItemTemplate> <h1><%#Eval("Title")%></h1> Directed by: <%#Eval("Director") %> <br /> Box Office Totals: <%#Eval("BoxOfficeTotals","{0:c}") %> </ItemTemplate> </asp:DataList> <asp:SqlDataSource ConnectionString="<%$ ConnectionStrings:Movies %>" SelectCommand="SELECT Title,Director,BoxOfficeTotals FROM Movies" Runat="server" /> </div> </form> </body> </html> | The DataList in Listing 13.6 renders an HTML table. Each data item is rendered into a separate table cell (<td> tag). The rendered output of the DataList control in Listing 13.6 looks like this: <table cellspacing="0" border="0" > <tr> <td> <h1>Titanic</h1> Directed by: James Cameron <br /> Box Office Totals: $600,000,000.00 </td> </tr> <tr> <td> <h1>Star Wars</h1> Directed by: George Lucas <br /> Box Office Totals: $500,000,000.00 </td> </tr> ... </table> The default behavior of the DataList control is to render an HTML table. However, you can override this default behavior and display the contents of each data item in a separate HTML <span> tag. This approach is illustrated in Listing 13.7. Listing 13.7. ShowFlowDataList.aspx <%@ Page Language="VB" %> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>Show Flow DataList</title> </head> <body> <form runat="server"> <div> <asp:DataList DataSource RepeatLayout="Flow" Runat="server"> <ItemTemplate> <%#Eval("Title")%> </ItemTemplate> </asp:DataList> <asp:SqlDataSource ConnectionString="<%$ ConnectionStrings:Movies %>" SelectCommand="SELECT Title FROM Movies" Runat="server" /> </div> </form> </body> </html> | Notice that the DataList control in Listing 13.7 includes a RepeatLayout property that has the value Flow. Each movie title is rendered in a <span> tag followed by a line-break tag (<br>). The RepeatLayout property accepts one of the following two values: Displaying Data in Multiple Columns You can render the contents of a DataList control into a multi-column table in which each data item occupies a separate table cell. Two properties modify the layout of the HTML table rendered by the DataList control: For example, the page in Listing 13.8 displays the contents of the Movies database table in a three-column layout (see Figure 13.6). Figure 13.6. Displaying a multi-column DataList. Listing 13.8. MultiColumnDataList.aspx <%@ Page Language="VB" %> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>MultiColumn DataList</title> </head> <body> <form runat="server"> <div> <asp:DataList DataSource RepeatColumns="3" GridLines="Both" Runat="server"> <ItemTemplate> <h1><%#Eval("Title")%></h1> Directed by: <%#Eval("Director") %> <br /> Box Office Totals: <%#Eval("BoxOfficeTotals","{0:c}") %> </ItemTemplate> </asp:DataList> <asp:SqlDataSource ConnectionString="<%$ ConnectionStrings:Movies %>" SelectCommand="SELECT Title,Director,BoxOfficeTotals FROM Movies" Runat="server" /> </div> </form> </body> </html> | Notice that the DataList control in Listing 13.8 includes a RepeatColumns property that has the value 3. If you set the RepeatDirection property to the value Horizontal and do not assign a value to the RepeatColumns property, then the DataList renders its data items horizontally without end. Note You can display data items in multiple columns when the DataList is in Flow layout mode. In that case, <br> tags are used to create the row breaks. Using Templates with the DataList Control The DataList control supports all the same templates as the Repeater control: ItemTemplate Formats each item from the data source. AlternatingItemTemplate Formats every other item from the data source. SeparatorTemplate Formats between each item from the data source. HeaderTemplate Formats before all items from the data source. FooterTemplate Formats after all items from the data source In addition, the DataList supports the following templates: The DataList control in Listing 13.9 includes both a HeaderTemplate and a FooterTemplate. The HeaderTemplate contains the caption for the table. The FooterTemplate contains a Label control that displays the total for all the preceding rows (see Figure 13.7). Figure 13.7. Displaying a HeaderTemplate and FooterTemplate. Listing 13.9. ShowDataListTemplates.aspx [View full width] <%@ Page Language="VB" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <script runat="server"> Dim totals As Decimal Protected Sub dlstMovies_ItemDataBound(ByVal sender As Object, ByVal e As DataListItemEventArgs) If Not IsNothing(e.Item.DataItem) Then totals += CType(DataBinder.Eval(e.Item.DataItem, "BoxOfficeTotals"), Decimal) End If If e.Item.ItemType = ListItemType.Footer Then Dim lblTotal As Label = CType(e.Item.FindControl("lblTotal"), Label) lblTotal.Text = totals.ToString("c") End If End Sub </script> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <style type="text/css"> .movies td { padding:10px; text-align:right; } </style> <title>Show DataList Templates</title> </head> <body> <form runat="server"> <div> <asp:DataList DataSource GridLines="Horizontal" UseAccessibleHeader="true" OnItemDataBound="dlstMovies_ItemDataBound" Css Runat="server" > <HeaderTemplate> Movie Box Office Totals </HeaderTemplate> <ItemTemplate> <%#Eval("Title")%>: <%#Eval("BoxOfficeTotals","{0:c}") %> </ItemTemplate> <FooterTemplate> <b>Total:</b> <asp:Label Runat="server" /> </FooterTemplate> </asp:DataList> <asp:SqlDataSource ConnectionString="<%$ ConnectionStrings:Movies %>" SelectCommand="SELECT Title,BoxOfficeTotals FROM Movies" Runat="server" /> </div> </form> </body> </html> | The total displayed in the FooterTemplate is calculated by the ItemDataBound event handler. The Label control is extracted by the FindControl() method and the total is assigned to the control's Text property. Selecting Data with the DataList Control You can use a DataList control as a menu by taking advantage of the control's SelectedValue property. For example, the page in Listing 13.10 enables you to pick a movie category and display a list of matching movies (see Figure 13.8). Listing 13.10. SelectDataList.aspx <%@ Page Language="VB" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <style type="text/css"> html { background-color:orange; } .content { margin:auto; width:600px; background-color:white; } .column { float:left; width:250px; padding:20px; } .movies td { padding:10px; } a { padding:10px; color:red; } a:hover { background-color:Gold; } </style> <title>Select DataList</title> </head> <body> <form runat="server"> <div > <div > <asp:DataList DataSource DataKeyField="Id" GridLines="Both" Css Runat="server"> <ItemTemplate> <asp:LinkButton Text='<%#Eval("Name") %>' CommandName="Select" Runat="server" /> </ItemTemplate> </asp:DataList> </div> <div > <asp:DataList DataSource Runat="server"> <ItemTemplate> <h1><%#Eval("Title")%></h1> Directed by: <%#Eval("Director") %> <br /> Box Office Totals: <%#Eval("BoxOfficeTotals","{0:c}") %> </ItemTemplate> </asp:DataList> </div> <br /> </div> <asp:SqlDataSource ConnectionString="<%$ ConnectionStrings:Movies %>" SelectCommand="SELECT Id, Name FROM MovieCategories" Runat="server" /> <asp:SqlDataSource ConnectionString="<%$ ConnectionStrings:Movies %>" SelectCommand="SELECT Title,Director,BoxOfficeTotals FROM Movies WHERE CategoryId=@CategoryId" Runat="server"> <SelectParameters> <asp:ControlParameter Name="CategoryId" Control PropertyName="SelectedValue" /> </SelectParameters> </asp:SqlDataSource> </form> </body> </html> | Figure 13.8. Selecting a row in the DataList. The page in Listing 13.10 contains two DataList controls. The first control displays a menu of movie categories and the second DataList control displays a list of matching movies. Notice that the first DataList in Listing 13.10 includes a DataKeyField property. The DataKeyField property accepts the name of a primary key column from the data source. When this property is set, the DataList control's DataKeys collection is populated with the primary keys from the data source when the control is bound to its data source. The first DataList contains a LinkButton inside its ItemTemplate, which looks like this: <asp:LinkButton Text='<%#Eval("Name") %>' CommandName="Select" Runat="server" /> Because the LinkButton control's CommandName property has the value Select, clicking the button changes the value of the DataList control's SelectedValue property. The DataList control's SelectedValue property is used by the second SqlDataSource control to return movies that match the selected category. Note Unlike the GridView, DetailsView, and FormView controls, you cannot assign the names of multiple primary key columns to the DataKeyField property. Editing Data with the DataList Control You can use the DataList control to edit database records. However, editing with the DataList control requires more coding than editing with other DataBound controls such as the GridView, FormView, or DetailsView controls. The page in Listing 13.11 illustrates how you can edit and delete database records with the DataList control (see Figure 13.9). Figure 13.9. Editing database records with the DataList control. Listing 13.11. EditDataList.aspx [View full width] <%@ Page Language="VB" MaintainScrollPositionOnPostback="true" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <script runat="server"> Protected Sub dlstMovies_EditCommand(ByVal source As Object, ByVal e As DataListCommandEventArgs) dlstMovies.EditItemIndex = e.Item.ItemIndex dlstMovies.DataBind() End Sub Protected Sub dlstMovies_UpdateCommand(ByVal source As Object, ByVal e As DataListCommandEventArgs) ' Get form fields Dim txtTitle As TextBox = CType(e.Item.FindControl("txtTitle"), TextBox) Dim txtDirector As TextBox = CType(e.Item.FindControl("txtDirector"), TextBox) Dim chkInTheaters As CheckBox = CType(e.Item.FindControl("chkInTheaters"), CheckBox) ' Assign parameters srcMovies.UpdateParameters("Id").DefaultValue = dlstMovies.DataKeys(e.Item .ItemIndex).ToString() srcMovies.UpdateParameters("Title").DefaultValue = txtTitle.Text srcMovies.UpdateParameters("Director").DefaultValue = txtDirector.Text srcMovies.UpdateParameters("InTheaters").DefaultValue = chkInTheaters.Checked.ToString() ' Call SqlDataSource Update srcMovies.Update() ' Take out of Edit mode dlstMovies.EditItemIndex = -1 End Sub Protected Sub dlstMovies_DeleteCommand(ByVal source As Object, ByVal e As DataListCommandEventArgs) ' Assign parameters srcMovies.DeleteParameters("Id").DefaultValue = dlstMovies.DataKeys(e.Item .ItemIndex).ToString() ' Call SqlDataSource Delete srcMovies.Delete() End Sub Protected Sub dlstMovies_CancelCommand(ByVal source As Object, ByVal e As DataListCommandEventArgs) dlstMovies.EditItemIndex = -1 dlstMovies.DataBind() End Sub </script> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <style type="text/css"> html { background-color:silver; } .movies { background-color:white; } .movies td,.movies th { padding:10px; border:solid 1px black; } .edit { background-color:yellow; } a { color:blue; } </style> <title>Edit DataList</title> </head> <body> <form runat="server"> <div> <asp:DataList DataSource DataKeyField="Id" GridLines="None" OnEditCommand="dlstMovies_EditCommand" OnCancelCommand="dlstMovies_CancelCommand" OnUpdateCommand="dlstMovies_UpdateCommand" OnDeleteCommand="dlstMovies_DeleteCommand" Css EditItemStyle-Css Runat="server"> <ItemTemplate> <h1><%#Eval("Title")%></h1> Directed by: <%#Eval("Director") %> <br /> In Theaters: <%#Eval("InTheaters") %> <br /><br /> <asp:LinkButton CommandName="Edit" Text="Edit" Runat="server" /> | <asp:LinkButton CommandName="Delete" Text="Delete" OnClientClick="return confirm('Are you sure?');" Runat="server" /> </ItemTemplate> <EditItemTemplate> <asp:Label Text="Title:" AssociatedControl Runat="server" /> <br /> <asp:TextBox Text='<%#Eval("Title")%>' Runat="server" /> <br /><br /> <asp:Label Text="Director:" AssociatedControl Runat="server" /> <br /> <asp:TextBox Text='<%#Eval("Director")%>' Runat="server" /> <br /><br /> <asp:CheckBox Text="In Theaters" Checked='<%#Eval("InTheaters")%>' Runat="server" /> <br /><br /> <asp:LinkButton CommandName="Update" Text="Update" Runat="server" /> | <asp:LinkButton CommandName="Cancel" Text="Cancel" Runat="server" /> </EditItemTemplate> </asp:DataList> <asp:SqlDataSource ConnectionString="<%$ ConnectionStrings:Movies %>" SelectCommand="SELECT Id,Title,Director,InTheaters FROM Movies" UpdateCommand="UPDATE Movies SET Title=@Title, Director=@Director,InTheaters=@InTheaters WHERE Id=@Id" DeleteCommand="DELETE Movies WHERE Id=@Id" Runat="server"> <UpdateParameters> <asp:Parameter Name="Id" /> <asp:Parameter Name="Title" /> <asp:Parameter Name="Director" /> <asp:Parameter Name="InTheaters" /> </UpdateParameters> <DeleteParameters> <asp:Parameter Name="Id" /> </DeleteParameters> </asp:SqlDataSource> </div> </form> </body> </html> | The ItemTemplate contained in the DataList in Listing 13.11 includes an Edit LinkButton and a Delete LinkButton. When you click the Edit LinkButton, the DataList raises its EditCommand event and the dlstMovies_Edit() method is executed. Clicking the Delete LinkButton raises the DeleteCommand event and the dlstMovies_Delete() method is executed. The dlstMovies_Edit() method sets the EditItemIndex property of the DataList control. The EditItemTemplate is displayed for the item in the DataList that matches the EditItemIndex. The EditItemTemplate includes form fields for editing a movie record and an Update and Cancel LinkButton. These LinkButtons raise the UpdateCommand and CancelCommand events, and execute the corresponding event handlers. Note Notice that the <%@ Page %> directive includes a MaintainScrollPositionOnPostback attribute. This attribute causes a page to scroll to the same position whenever you post the page back to the server. For example, when you click the Edit link next to a row in the DataList, the page scrolls to the Edit link that you clicked. This attribute works with Internet Explorer 6+, FireFox 1+, and Opera 8+. Formatting the DataList Control The DataList control includes a rich set of properties that you can use to format the HTML rendered by the control. If you want to associate Cascading Style Sheet rules with different elements of the DataList, then you can take advantage of any of the following properties: CssClass Enables you to associate a CSS class with the DataList. AlternatingItemStyle Enables you to format every other row of the DataList. EditItemStyle Enables you to format the DataList row selected for editing. FooterStyle Enables you to format the footer row of the DataList. HeaderStyle Enables you to format the header row of the DataList. ItemStyle Enables you to format each row displayed by the DataList. SelectedItemStyle Enables you to format the selected row in the DataList. SeparatorStyle Enables you to format the row separator displayed by the DataList. When formatting the DataList, you also need to work with the following properties: GridLines Enables you to add rules around the cells in the DataList. Possible values are None, Horizontal, Vertical, and Both. ShowFooter Enables you to show or hide the footer row. ShowHeader Enables you to show or hide the header row. UseAccessibleHeader Enables you to render HTML <th> tags instead of <td> tags for the cells in the header row. Web Standards Note To make a page that contains a DataList more accessible to persons with disabilities, you should always include a HeaderTemplate and enable the UserAccessibleHeader property. The page in Listing 13.12 illustrates how you can take advantage of several of these formatting properties (see Figure 13.10). Figure 13.10. Formatting a DataList. Listing 13.12. FormatDataList.aspx <%@ Page Language="VB" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <style type="text/css"> html { background-color:#Silver; } .movies { font:14px Arial,Sans-Serif; } .header { font-size:18px; letter-spacing:15px; } .item { padding:5px; background-color:#eeeeee; border-bottom:Solid 1px blue; } .alternating { padding:5px; background-color:LightBlue; border-bottom:Solid 1px blue; } </style> <title>Format DataList</title> </head> <body> <form runat="server"> <div> <asp:DataList DataSource UseAccessibleHeader="true" Css HeaderStyle-Css ItemStyle-Css AlternatingItemStyle-Css Runat="server"> <HeaderTemplate> Movies </HeaderTemplate> <ItemTemplate> <%#Eval("Title")%> </ItemTemplate> </asp:DataList> <asp:SqlDataSource ConnectionString="<%$ ConnectionStrings:Movies %>" SelectCommand="SELECT Title FROM Movies" Runat="server" /> </div> </form> </body> </html> | |