Chapter 13. Using the Repeater and DataList Controls

<feature><title>In this Chapter</title> <objective>

Using the Repeater Control

</objective>
<objective>

Using the DataList Control

</objective>
<objective>

Summary

</objective>
</feature>

Both the Repeater and DataList controls—the subjects of this chapter—enable you to display a set of data items at a time. For example, you can use these controls to display all the rows contained in a database table.

The Repeater control is entirely template driven. You can format the rendered output of the control in any way that you please. For example, you can use the Repeater control to display records in a bulleted list, a set of HTML tables, or even in a comma-delimited list.

The DataList control is also template driven. However, unlike the Repeater control, the default behavior of the DataList control is to render its contents into an HTML table. The DataList control renders each record from its data source into a separate HTML table cell.

In this chapter, you learn how to use both of these controls to display database data. You also learn how to use each of the different types of templates that each of the controls supports. Finally, you can see how to handle the different types of events that the controls expose.

Using the Repeater Control

The Repeater control provides you with the maximum amount of flexibility in rendering a set of database records. You can format the output of the Repeater control in any way that you please. In this section, you learn how to display data with the Repeater control and handle Repeater control events.

Displaying Data with the Repeater Control

To display data with the Repeater control, you must create an ItemTemplate. For example, the page in Listing 13.1 displays the contents of the Movies database table (see Figure 13.1).

Displaying data with a Repeater Control.

Figure 13.1. Displaying data with a Repeater Control.

Example 13.1. ShowRepeater.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 id="Head1" runat="server">
    <style type="text/css">
    html
    {
        background-color:silver;
    }
    .content
    {
        width:600px;
        border:solid 1px black;
        background-color:#eeeeee;
    }
    .movies
    {
        margin:20px 10px;
        padding:10px;
        border:dashed 2px black;
        background-color:white;
    }
    </style>
    <title>Show Repeater</title>
</head>
<body>
    <form id="form1" runat="server">
    <div class="content">

    <asp:Repeater
        id="rptMovies"
        DataSourceID="srcMovies"
        Runat="server">
        <ItemTemplate>
        <div class="movies">
        <h1><%#Eval("Title") %></h1>
        <b>Directed by:</b> <%# Eval("Director") %>
        <br />
        <b>Box Office Totals:</b> <%# Eval("BoxOfficeTotals","{0:c}") %>
        </div>
        </ItemTemplate>
    </asp:Repeater>

    <asp:SqlDataSource
        id="srcMovies"
        ConnectionString="<%$ ConnectionStrings:Movies %>"
        SelectCommand="SELECT Title,Director,BoxOfficeTotals
            FROM Movies"
        Runat="server" />

    </div>
    </form>
</body>
</html>

The Repeater control in Listing 13.1 displays each record in a separate HTML <div> tag. A databinding expression is used to display the value of each column.

In Listing 13.1, declarative databinding is used to bind the Repeater to the SqlDataSource. You also can databind a Repeater control programmatically.

For example, the page in Listing 13.2 contains a Repeater control that renders a JavaScript array. The Repeater control is programmatically databound to the list of files in the Photos directory.

Example 13.2. ShowRepeaterPhotos.aspx

<%@ Page Language="VB" %>
<%@ Import Namespace="System.IO" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
   "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<script runat="server">

    Sub Page_Load()
        If Not Page.IsPostBack Then
            Dim dir As New DirectoryInfo(MapPath("~/Photos"))
            rptPhotos.DataSource = dir.GetFiles("*.jpg")
            rptPhotos.DataBind()
        End If
    End Sub
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
    <style type="text/css">
        .photo
        {
            width:400px;
            background-color:white;
            filter:progid:DXImageTransform.Microsoft.Fade(duration=2);
        }
    </style>
    <script type="text/javascript">
    var photos = new Array();
    window.setInterval(showImage, 5000);

    function showImage()
    {
        if (photos.length > 0)
        {
            var index = Math.floor(Math.random() * photos.length);
            var image = document.getElementById('imgPhoto'),
            image.src = photos[index];
            if (image.filters)
            {
                image.filters[0].Apply();
                image.filters[0].Play();
            }
        }
    }
    </script>
    <title>Show Repeater Photos</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>

    <img id="imgPhoto" alt="" class="photo" />
    <script type="text/javascript">
    <asp:Repeater
        id="rptPhotos"
        Runat="server">
        <ItemTemplate>
        <%# Eval("Name", "photos.push('Photos/{0}')") %>
        </ItemTemplate>
    </asp:Repeater>
    showImage();
    </script>

    </div>
    </form>
</body>
</html>

The page in Listing 13.2 randomly displays a different photo every five seconds. A random image is selected from the JavaScript array and displayed by the JavaScript showImage() function. An Internet Explorer transition filter is used to create a fade-in effect.

Web Standards Note

The transition filter is an Internet Explorer–only extension to Cascading Style Sheets. The page still works with Opera 8 and Firefox 1, but you don’t get the fade-in effect.

Using Templates with the Repeater Control

The Repeater control supports five different types of templates:

  • 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.

You are required to use only an ItemTemplate; the other types of templates can be used at your own discretion. The order in which you declare the templates in the Repeater control does not matter.

You can use the AlternatingItemTemplate to create a banding effect (as in old-time computer paper). In other words, you can use the AlternatingItemTemplate to display alternating rows with a different background color. This approach is illustrated by the page in Listing 13.3 (see Figure 13.2).

Displaying an HTML table with the Repeater control.

Figure 13.2. Displaying an HTML table with the Repeater control.

Example 13.3. ShowRepeaterTable.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 id="Head1" runat="server">
    <style type="text/css">
    html
    {
        background-color:silver;
    }
    .content
    {
        width:600px;
        border:solid 1px black;
        background-color:white;
    }
    .movies
    {
        border-collapse:collapse;
    }
    .movies th,.movies td
    {
        padding:10px;
        border-bottom:1px solid black;
    }
    .alternating
    {
        background-color:#eeeeee;
    }
    </style>
    <title>Show Repeater Table</title>
</head>
<body>
    <form id="form1" runat="server">
    <div class="content">

    <asp:Repeater
        id="rptMovies"
        DataSourceID="srcMovies"
        Runat="server">
        <HeaderTemplate>
        <table class="movies">
        <tr>
            <th>Movie Title</th>
            <th>Movie Director</th>
            <th>Box Office Totals</th>
        </tr>
        </HeaderTemplate>
        <ItemTemplate>
        <tr>
            <td><%#Eval("Title") %></td>
            <td><%#Eval("Director") %></td>
            <td><%#Eval("BoxOfficeTotals","{0:c}") %></td>
        </tr>
        </ItemTemplate>
        <AlternatingItemTemplate>
        <tr class="alternating">
            <td><%#Eval("Title") %></td>
            <td><%#Eval("Director") %></td>
            <td><%#Eval("BoxOfficeTotals","{0:c}") %></td>
        </tr>
        </AlternatingItemTemplate>
        <FooterTemplate>
        </table>
        </FooterTemplate>
    </asp:Repeater>

    <asp:SqlDataSource
        id="srcMovies"
        ConnectionString="<%$ ConnectionStrings:Movies %>"
        SelectCommand="SELECT Title,Director,BoxOfficeTotals
            FROM Movies"
        Runat="server" />

    </div>
    </form>
</body>
</html>

The Repeater control in Listing 13.3 renders an HTML table in which every other row appears with a gray background color. Notice that this Repeater control uses four out of five of the templates supported by the Repeater: the ItemTemplate, AlternatingItemTemplate, HeaderTemplate, and FooterTemplate.

Notice that the AlternatingItemTemplate contains almost exactly the same content as the ItemTemplate. The only difference is that the <tr> tag includes a class attribute that changes its background color.

The SeparatorTemplate is used to add content between each data item from the data source. For example, the page in Listing 13.4 uses a SeparatorItemTemplate to create a tab strip with the Repeater control (see Figure 13.3).

Displaying a tab strip with the Repeater control.

Figure 13.3. Displaying a tab strip with the Repeater control.

Example 13.4. ShowSeparatorTemplate.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 id="Head1" runat="server">
    <style type="text/css">
    html
    {
        background-color:silver;
    }
    .content
    {
        width:600px;
        height:400px;
        padding:10px;
        border:solid 1px black;
        background-color:white;
    }
    a
    {
        color:blue;
    }
    </style>
    <title>Show SeparatorTemplate</title>
</head>
<body>
    <form id="form1" runat="server">
    <div class="content">

    <asp:Repeater
        id="rptMovieCategories"
        DataSourceID="srcMovieCategories"
        Runat="server">
        <ItemTemplate>
        <asp:HyperLink
            id="lnkMenu"
            Text='<%#Eval("Name")%>'
            NavigateUrl='<%#Eval("Id","ShowSeparatorTemplate.aspx?id={0}")%>'
            Runat="server" />
        </ItemTemplate>
        <SeparatorTemplate>
        &nbsp;|&nbsp;
        </SeparatorTemplate>
    </asp:Repeater>

    <asp:Repeater
        id="rptMovies"
        DataSourceID="srcMovies"
        Runat="server">
        <HeaderTemplate>
        <ul>
        </HeaderTemplate>
        <ItemTemplate>
        <li><%#Eval("Title")%></li>
        </ItemTemplate>
        <FooterTemplate>
        </ul>
        </FooterTemplate>
    </asp:Repeater>

    <asp:SqlDataSource
        id="srcMovieCategories"
        ConnectionString="<%$ ConnectionStrings:Movies %>"
        SelectCommand="SELECT Id, Name
            FROM MovieCategories"
        Runat="server" />

    <asp:SqlDataSource
        id="srcMovies"
        ConnectionString="<%$ ConnectionStrings:Movies %>"
        SelectCommand="SELECT Title FROM Movies
            WHERE CategoryId=@CategoryId"
        Runat="server">
        <SelectParameters>
        <asp:QueryStringParameter
             Name="CategoryId"
             QueryStringField="Id" />
        </SelectParameters>
    </asp:SqlDataSource>

    </div>
    </form>
</body>
</html>

The page in Listing 13.4 contains two Repeater controls. The first Repeater control displays a tab strip of movie categories. The second Repeater control displays a bulleted list of matching movies.

Handling Repeater Control Events

The Repeater control supports the following events:

  • DataBindingRaised when the Repeater control is bound to its data source.

  • ItemCommandRaised when a control contained in the Repeater control raises an event.

  • ItemCreatedRaised when each Repeater item is created.

  • ItemDataBoundRaised when each Repeater item is bound.

The page in Listing 13.5 illustrates how you can use the DataBinding, ItemCommand, and ItemDataBound events. This page uses a Repeater control to update, delete, and insert database records (see Figure 13.4).

Editing database records with the Repeater control.

Figure 13.4. Editing database records with the Repeater control.

Example 13.5. EditRepeater.aspx

<%@ Page Language="VB" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
   "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<script runat="server">

    ' The name of the primary key column
    Dim DataKeyName As String = "Id"

    ''' <summary>
    ''' Stores the primary keys in ViewState
    ''' </summary>
    ReadOnly Property Keys() As Hashtable
        Get
            If IsNothing(ViewState("Keys")) Then
                ViewState("Keys") = New Hashtable()
            End If
            Return CType(ViewState("Keys"), Hashtable)
        End Get
    End Property

    ''' <summary>
    ''' Build the primary key collection
    ''' </summary>
    Protected Sub rptMovies_ItemDataBound(ByVal sender As Object, ByVal e As RepeaterItemEventArgs)
        If e.Item.ItemType = ListItemType.Item Or e.Item.ItemType = ListItemType.AlternatingItem Then
            Keys.Add(e.Item.ItemIndex, DataBinder.Eval(e.Item.DataItem, "Id"))
        End If
    End Sub

    ''' <summary>
    ''' Clear the primary keys when Repeater is rebound
    ''' to its data source
    ''' </summary>
    Protected Sub rptMovies_DataBinding(ByVal sender As Object, ByVal e As EventArgs)
        Keys.Clear()
    End Sub

    ''' <summary>
    ''' When you click the Update,Insert, or Delete
    ''' button, this method executes
    ''' </summary>
    Protected Sub rptMovies_ItemCommand(ByVal source As Object, ByVal e As RepeaterCommandEventArgs)
        Select Case e.CommandName
            Case "Update"
                UpdateMovie(e)
                Exit Sub
            Case "Insert"
                InsertMovie(e)
                Exit Sub
            Case "Delete"
                DeleteMovie(e)
                Exit Sub
        End Select
    End Sub

    ''' <summary>
    ''' Update a movie record
    ''' </summary>
    Private Sub UpdateMovie(ByVal e As RepeaterCommandEventArgs)
        ' Get the 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)

        ' Set the DataSource parameters
        srcMovies.UpdateParameters("Id").DefaultValue = Keys(e.Item.ItemIndex).ToString()
        srcMovies.UpdateParameters("Title").DefaultValue = txtTitle.Text
        srcMovies.UpdateParameters("Director").DefaultValue = txtDirector.Text
        srcMovies.UpdateParameters("InTheaters").DefaultValue = chkInTheaters.Checked.ToString()

        ' Fire the UpdateCommand
        srcMovies.Update()
    End Sub

    ''' <summary>
    ''' Insert a movie record
    ''' </summary>
    Private Sub InsertMovie(ByVal e As RepeaterCommandEventArgs)
        ' Get the 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)

        ' Set the DataSource parameters
        srcMovies.InsertParameters("Title").DefaultValue = txtTitle.Text
        srcMovies.InsertParameters("Director").DefaultValue = txtDirector.Text
        srcMovies.InsertParameters("InTheaters").DefaultValue = chkInTheaters.Checked.ToString()

        ' Fire the InsertCommand
        srcMovies.Insert()
    End Sub

    ''' <summary>
    ''' Delete a movie record
    ''' </summary>
    Private Sub DeleteMovie(ByVal e As RepeaterCommandEventArgs)
        ' Set the DataSource parameters
        srcMovies.DeleteParameters("Id").DefaultValue = Keys(e.Item.ItemIndex).ToString()

        ' Fire the DeleteCommand
        srcMovies.Delete()
    End Sub
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
    <style type="text/css">
    html
    {
        background-color:silver;
    }
    .content
    {
        width:600px;
        height:400px;
        padding:10px;
        border:solid 1px black;
        background-color:white;
    }
    .movies td
    {
        text-align:center;
    }
    a
    {
        color:blue;
    }
    </style>
    <title>Edit Repeater</title>
</head>
<body>
    <form id="form1" runat="server">
    <div class="content">

    <asp:Repeater
        id="rptMovies"
        DataSourceID="srcMovies"
        OnItemCommand="rptMovies_ItemCommand"
        OnItemDataBound="rptMovies_ItemDataBound"
        OnDataBinding="rptMovies_DataBinding"
        Runat="server">
        <HeaderTemplate>
        <table class="movies">
        <tr>
            <th>Title</th>
            <th>Director</th>
            <th>In Theaters</th>
        </tr>
        </HeaderTemplate>
        <ItemTemplate>
        <tr>
            <td>
            <asp:TextBox
                id="txtTitle"
                Text='<%#Eval("Title")%>'
                Runat="server" />
            </td>
            <td>
            <asp:TextBox
                id="txtDirector"
                Text='<%#Eval("Director")%>'
                Runat="server" />
            </td>
            <td>
            <asp:CheckBox
                id="chkInTheaters"
                Checked='<%#Eval("InTheaters")%>'
                Runat="server" />
            </td>
            <td>
            <asp:LinkButton
                id="lnkUpdate"
                CommandName="Update"
                Text="Update"
                Runat="server" />
            &nbsp;|&nbsp;
            <asp:LinkButton
                id="lnkDelete"
                CommandName="Delete"
                Text="Delete"
                OnClientClick="return confirm('Are you sure?'),"
                Runat="server" />
            </td>
        </tr>
        </ItemTemplate>
        <FooterTemplate>
        <tr>
            <td>
            <asp:TextBox
                id="txtTitle"
                Runat="server" />
            </td>
            <td>
            <asp:TextBox
                id="txtDirector"
                Runat="server" />
            </td>
            <td>
            <asp:CheckBox
                id="chkInTheaters"
                Runat="server" />
            </td>
            <td>
            <asp:LinkButton
                id="lnkInsert"
                CommandName="Insert"
                Text="Insert"
                Runat="server" />
            </td>
        </tr>
        </table>
        </FooterTemplate>
    </asp:Repeater>

    <asp:SqlDataSource
        id="srcMovies"
        ConnectionString="<%$ ConnectionStrings:Movies %>"
        SelectCommand="SELECT Id,Title,Director,InTheaters
            FROM Movies"
        UpdateCommand="UPDATE Movies SET Title=@Title,
            Director=@Director,InTheaters=@InTheaters
            WHERE Id=@Id"
        InsertCommand="INSERT Movies (Title,Director,InTheaters)
            VALUES (@Title,@Director,@InTheaters)"
        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>
        <InsertParameters>
            <asp:Parameter Name="Title" />
            <asp:Parameter Name="Director" />
            <asp:Parameter Name="InTheaters" />
        </InsertParameters>
        <DeleteParameters>
            <asp:Parameter Name="Id" />
        </DeleteParameters>
    </asp:SqlDataSource>

    </div>
    </form>
</body>
</html>

In Listing 13.5, the ItemDataBound event handler builds a collection of primary keys from the data source. The collection of primary keys is stored in ViewState so that they will be available after a postback to the server.

The DataBinding event handler clears the primary key collection when the Repeater is rebound to its data source (after a record is updated or deleted). If you don’t clear the collection, then you get duplicates of the primary keys and an exception is raised.

The ItemCommand event handler takes care of processing the button click events. When you click an Insert, Update, or Delete button, the event bubbles up and raises the ItemCommmand event. The ItemCommand event handler grabs the values from the form fields and calls the Insert(), Update(), or Delete() methods of the SqlDataSource control.

Using the DataList Control

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).

Displaying database records with the DataList control.

Figure 13.5. Displaying database records with the DataList control.

Example 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 id="Head1" runat="server">
    <title>Show DataList</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>

    <asp:DataList
        id="dlstMovies"
        DataSourceID="srcMovies"
        Runat="server">
        <ItemTemplate>
        <h1><%#Eval("Title")%></h1>
        Directed by:
        <%#Eval("Director") %>
        <br />
        Box Office Totals:
        <%#Eval("BoxOfficeTotals","{0:c}") %>
        </ItemTemplate>
    </asp:DataList>

    <asp:SqlDataSource
        id="srcMovies"
        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 id="dlstMovies" cellspacing="0" border="0"
  style="border-collapse:collapse;">
<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.

Example 13.7. ShowFlowDataList.aspx

<%@ Page Language="VB" %>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
    <title>Show Flow DataList</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>

    <asp:DataList
        id="dlstMovies"
        DataSourceID="srcMovies"
        RepeatLayout="Flow"
        Runat="server">
        <ItemTemplate>
        <%#Eval("Title")%>
        </ItemTemplate>
    </asp:DataList>

    <asp:SqlDataSource
        id="srcMovies"
        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:

  • TableData Items are rendered in HTML table cells.

  • FlowData Items are rendered in HTML <span> tags.

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:

  • RepeatColumnsThe number of columns to display.

  • RepeatDirectionThe direction to render the cells. Possible values are Horizontal and Vertical.

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).

Displaying a multi-column DataList.

Figure 13.6. Displaying a multi-column DataList.

Example 13.8. MultiColumnDataList.aspx

<%@ Page Language="VB" %>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
    <title>MultiColumn DataList</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>

    <asp:DataList
        id="dlstMovies"
        DataSourceID="srcMovies"
        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
        id="srcMovies"
        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:

  • EditItemTemplateDisplayed when a row is selected for editing.

  • SelectedItemTemplateDisplayed when a row is selected.

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).

Displaying a HeaderTemplate and FooterTemplate.

Figure 13.7. Displaying a HeaderTemplate and FooterTemplate.

Example 13.9. ShowDataListTemplates.aspx

<%@ 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 id="Head1" runat="server">
    <style type="text/css">
    .movies td
    {
        padding:10px;
        text-align:right;
    }
    </style>
    <title>Show DataList Templates</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>

    <asp:DataList
        id="dlstMovies"
        DataSourceID="srcMovies"
        GridLines="Horizontal"
        UseAccessibleHeader="true"
        OnItemDataBound="dlstMovies_ItemDataBound"
        CssClass="movies"
        Runat="server" >
        <HeaderTemplate>
        Movie Box Office Totals
        </HeaderTemplate>
        <ItemTemplate>
        <%#Eval("Title")%>:
        <%#Eval("BoxOfficeTotals","{0:c}") %>
        </ItemTemplate>
        <FooterTemplate>
        <b>Total:</b>
        <asp:Label
            id="lblTotal"
            Runat="server" />
        </FooterTemplate>
    </asp:DataList>

    <asp:SqlDataSource
        id="srcMovies"
        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).

Example 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 id="Head1" 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 id="form1" runat="server">
    <div class="content">

    <div class="column">
    <asp:DataList
        id="dlstMovieCategories"
        DataSourceID="srcMovieCategories"
        DataKeyField="Id"
        GridLines="Both"
        CssClass="movies"
        Runat="server">
        <ItemTemplate>
        <asp:LinkButton
            id="lnkMovie"
            Text='<%#Eval("Name") %>'
            CommandName="Select"
            Runat="server" />
        </ItemTemplate>
    </asp:DataList>
    </div>

    <div class="column">
    <asp:DataList
        id="dlstMovieDetails"
        DataSourceID="srcMovieDetails"
        Runat="server">
        <ItemTemplate>
        <h1><%#Eval("Title")%></h1>
        Directed by:
        <%#Eval("Director") %>
        <br />
        Box Office Totals:
        <%#Eval("BoxOfficeTotals","{0:c}") %>
        </ItemTemplate>
    </asp:DataList>
    </div>
    <br style="clear:both" />
    </div>

    <asp:SqlDataSource
        id="srcMovieCategories"
        ConnectionString="<%$ ConnectionStrings:Movies %>"
        SelectCommand="SELECT Id, Name FROM MovieCategories"
        Runat="server" />

    <asp:SqlDataSource
        id="srcMovieDetails"
        ConnectionString="<%$ ConnectionStrings:Movies %>"
        SelectCommand="SELECT Title,Director,BoxOfficeTotals
            FROM Movies WHERE CategoryId=@CategoryId"
        Runat="server">
        <SelectParameters>
        <asp:ControlParameter
            Name="CategoryId"
            ControlID="dlstMovieCategories"
            PropertyName="SelectedValue" />
        </SelectParameters>
    </asp:SqlDataSource>
    </form>
</body>
</html>

Selecting a row in the DataList.

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
  id="lnkMovie"
  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).

Editing database records with the DataList control.

Figure 13.9. Editing database records with the DataList control.

Example 13.11. EditDataList.aspx

<%@ 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 id="Head1" 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 id="form1" runat="server">
    <div>

    <asp:DataList
        id="dlstMovies"
        DataSourceID="srcMovies"
        DataKeyField="Id"
        GridLines="None"
        OnEditCommand="dlstMovies_EditCommand"
        OnCancelCommand="dlstMovies_CancelCommand"
        OnUpdateCommand="dlstMovies_UpdateCommand"
        OnDeleteCommand="dlstMovies_DeleteCommand"
        CssClass="movies"
        EditItemStyle-CssClass="edit"
        Runat="server">
        <ItemTemplate>
        <h1><%#Eval("Title")%></h1>
        Directed by:
        <%#Eval("Director") %>
        <br />
        In Theaters:
        <%#Eval("InTheaters") %>
        <br /><br />
        <asp:LinkButton
            id="lnkEdit"
            CommandName="Edit"
            Text="Edit"
            Runat="server" />
        &nbsp;|&nbsp;
        <asp:LinkButton
            id="lnkDelete"
            CommandName="Delete"
            Text="Delete"
            OnClientClick="return confirm('Are you sure?'),"
            Runat="server" />
        </ItemTemplate>
        <EditItemTemplate>
        <asp:Label
            id="lblTitle"
            Text="Title:"
            AssociatedControlID="txtTitle"
            Runat="server" />
        <br />
        <asp:TextBox
            id="txtTitle"
            Text='<%#Eval("Title")%>'
            Runat="server" />
        <br /><br />
        <asp:Label
            id="lblDirector"
            Text="Director:"
            AssociatedControlID="txtDirector"
            Runat="server" />
        <br />
        <asp:TextBox
            id="txtDirector"
            Text='<%#Eval("Director")%>'
            Runat="server" />
        <br /><br />
        <asp:CheckBox
            id="chkInTheaters"
            Text="In Theaters"
            Checked='<%#Eval("InTheaters")%>'
            Runat="server" />
        <br /><br />
        <asp:LinkButton
            id="lnkUpdate"
            CommandName="Update"
            Text="Update"
            Runat="server" />
         &nbsp;|&nbsp;
        <asp:LinkButton
            id="lnkCancel"
            CommandName="Cancel"
            Text="Cancel"
            Runat="server" />
        </EditItemTemplate>
    </asp:DataList>

    <asp:SqlDataSource
        id="srcMovies"
        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:

  • CssClassEnables you to associate a CSS class with the DataList.

  • AlternatingItemStyleEnables you to format every other row of the DataList.

  • EditItemStyleEnables you to format the DataList row selected for editing.

  • FooterStyleEnables you to format the footer row of the DataList.

  • HeaderStyleEnables you to format the header row of the DataList.

  • ItemStyleEnables you to format each row displayed by the DataList.

  • SelectedItemStyleEnables you to format the selected row in the DataList.

  • SeparatorStyleEnables you to format the row separator displayed by the DataList.

When formatting the DataList, you also need to work with the following properties:

  • GridLinesEnables you to add rules around the cells in the DataList. Possible values are None, Horizontal, Vertical, and Both.

  • ShowFooterEnables you to show or hide the footer row.

  • ShowHeaderEnables you to show or hide the header row.

  • UseAccessibleHeaderEnables 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).

Formatting a DataList.

Figure 13.10. Formatting a DataList.

Example 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 id="Head1" 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 id="form1" runat="server">
    <div>

    <asp:DataList
        id="dlstMovies"
        DataSourceID="srcMovies"
        UseAccessibleHeader="true"
        CssClass="movies"
        HeaderStyle-CssClass="header"
        ItemStyle-CssClass="item"
        AlternatingItemStyle-CssClass="alternating"
        Runat="server">
        <HeaderTemplate>
        Movies
        </HeaderTemplate>
        <ItemTemplate>
        <%#Eval("Title")%>
        </ItemTemplate>
    </asp:DataList>

    <asp:SqlDataSource
        id="srcMovies"
        ConnectionString="<%$ ConnectionStrings:Movies %>"
        SelectCommand="SELECT Title FROM Movies"
        Runat="server" />

    </div>
    </form>
</body>
</html>

Summary

In this chapter, you learned how to use the Repeater control and the DataList controls to display a set of database records. First, you learned how to use the Repeater control to display and edit database records. For example, you learned how to use the Repeater control to enable users to edit, delete, and insert database records.

In the second half of this chapter, you learned how to work with the DataList control. You learned how to render both single and multi-column tables with the DataList control. You also learned how to selected rows with the DataList control. Finally, you learned how to edit records using the DataList control.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset