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). Figure 13.1. Displaying data with a Repeater Control. Listing 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 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 runat="server"> <div > <asp:Repeater DataSource Runat="server"> <ItemTemplate> <div > <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 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. Listing 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 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 runat="server"> <div> <img alt="" /> <script type="text/javascript"> <asp:Repeater 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 Exploreronly 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). Figure 13.2. Displaying an HTML table with the Repeater control. Listing 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 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 runat="server"> <div > <asp:Repeater DataSource Runat="server"> <HeaderTemplate> <table > <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 > <td><%#Eval("Title") %></td> <td><%#Eval("Director") %></td> <td><%#Eval("BoxOfficeTotals","{0:c}") %></td> </tr> </AlternatingItemTemplate> <FooterTemplate> </table> </FooterTemplate> </asp:Repeater> <asp:SqlDataSource 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). Figure 13.3. Displaying a tab strip with the Repeater control. Listing 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 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 runat="server"> <div > <asp:Repeater DataSource Runat="server"> <ItemTemplate> <asp:HyperLink Text='<%#Eval("Name")%>' NavigateUrl='<%#Eval("Id","ShowSeparatorTemplate.aspx?id={0}")%>' Runat="server" /> </ItemTemplate> <SeparatorTemplate> | </SeparatorTemplate> </asp:Repeater> <asp:Repeater DataSource Runat="server"> <HeaderTemplate> <ul> </HeaderTemplate> <ItemTemplate> <li><%#Eval("Title")%></li> </ItemTemplate> <FooterTemplate> </ul> </FooterTemplate> </asp:Repeater> <asp:SqlDataSource ConnectionString="<%$ ConnectionStrings:Movies %>" SelectCommand="SELECT Id, Name FROM MovieCategories" Runat="server" /> <asp:SqlDataSource 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: DataBinding Raised when the Repeater control is bound to its data source. ItemCommand Raised when a control contained in the Repeater control raises an event. ItemCreated Raised when each Repeater item is created. ItemDataBound Raised 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). Figure 13.4. Editing database records with the Repeater control. Listing 13.5. EditRepeater.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"> ' 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 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 runat="server"> <div > <asp:Repeater DataSource OnItemCommand="rptMovies_ItemCommand" OnItemDataBound="rptMovies_ItemDataBound" OnDataBinding="rptMovies_DataBinding" Runat="server"> <HeaderTemplate> <table > <tr> <th>Title</th> <th>Director</th> <th>In Theaters</th> </tr> </HeaderTemplate> <ItemTemplate> <tr> <td> <asp:TextBox Text='<%#Eval("Title")%>' Runat="server" /> </td> <td> <asp:TextBox Text='<%#Eval("Director")%>' Runat="server" /> </td> <td> <asp:CheckBox Checked='<%#Eval("InTheaters")%>' Runat="server" /> </td> <td> <asp:LinkButton CommandName="Update" Text="Update" Runat="server" /> | <asp:LinkButton CommandName="Delete" Text="Delete" OnClientClick="return confirm('Are you sure?');" Runat="server" /> </td> </tr> </ItemTemplate> <FooterTemplate> <tr> <td> <asp:TextBox Runat="server" /> </td> <td> <asp:TextBox Runat="server" /> </td> <td> <asp:CheckBox Runat="server" /> </td> <td> <asp:LinkButton CommandName="Insert" Text="Insert" Runat="server" /> </td> </tr> </table> </FooterTemplate> </asp:Repeater> <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" 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. |