ptg 544 CHAPTER 11 Using the GridView Control LISTING 11.27 ShowTemplateField.aspx <%@ Page Language=”C#” %> <!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 TemplateField</title> </head> <body> <form id=”form1” runat=”server”> <div> <asp:GridView id=”grdMovies” DataSourceID=”srcMovies” DataKeyNames=”Id” AutoGenerateColumns=”false” AutoGenerateEditButton=”true” Runat=”server”> <Columns> <asp:TemplateField HeaderText=”Title”> FIGURE 11.19 Using TemplateFields with the GridView control. From the Library of Wow! eBook ptg 545 Using Fields with the GridView Control 11 <ItemTemplate> <%# Eval(“Title”) %> </ItemTemplate> <EditItemTemplate> <asp:TextBox id=”txtTitle” Text=’<%# Bind(“Title”) %>’ Runat=”server” /> <asp:RequiredFieldValidator id=”valTitle” ControlToValidate=”txtTitle” Text=”(required)” Runat=”server” /> </EditItemTemplate> </asp:TemplateField> <asp:TemplateField HeaderText=”Category”> <ItemTemplate> <%# Eval(“Name”) %> </ItemTemplate> <EditItemTemplate> <asp:DropDownList id=”ddlCategory” DataSourceID=”srcMovieCategories” DataTextField=”Name” DataValueField=”Id” SelectedValue=’<%# Bind(“CategoryId”) %>’ Runat=”server” /> </EditItemTemplate> </asp:TemplateField> </Columns> </asp:GridView> <asp:SqlDataSource id=”srcMovies” ConnectionString=’<%$ ConnectionStrings:Movies %>’ SelectCommand=”SELECT Movies.Id, Title, CategoryId, Name FROM Movies JOIN MovieCategories ON MovieCategories.Id = Movies.CategoryId” UpdateCommand=”UPDATE Movies SET Title=@Title, CategoryId=@CategoryId WHERE Id=@Id” Runat=”server” /> <asp:SqlDataSource id=”srcMovieCategories” ConnectionString=’<%$ ConnectionStrings:Movies %>’ From the Library of Wow! eBook ptg 546 CHAPTER 11 Using the GridView Control SelectCommand=”SELECT Id, Name FROM MovieCategories” Runat=”server” /> </div> </form> </body> </html> GridView in Listing 11.27 contains two TemplateFields. The first TemplateField enables you to display and edit the value of the Title column. The contents of ItemTemplate display when a row is not selected for editing. The contents of EditItemTemplate display when the row is selected for editing. EditItemTemplate for the Title column includes a RequiredFieldValidator control. This RequiredFieldValidator control prevents a user from updating a record without entering a value for the Title column. The second TemplateField displays the value of the movie category column. EditItemTemplate contains a DropDownList control, which enables you to change the movie category associated with the record being edited. TemplateField supports the following six types of templates: . AlternatingItemTemplate—The contents of this template display for every other row rendered by GridView. . EditItemTemplate—The contents of this template display when a row is selected for editing. . FooterTemplate—The contents of this template display in the column footer. . HeaderTemplate—The contents of this template display in the column header. . InsertItemTemplate—The contents of this template display when a new data item is inserted (does not apply to the GridView control). . ItemTemplate—The contents of this template display for every row rendered by the GridView. Working with GridView Control Events The GridView control includes a rich set of events that you can handle to customize the control’s behavior and appearance. These events can be divided into three groups. First, the GridView control supports the following set of events raised when the control displays its rows: From the Library of Wow! eBook ptg 547 Working with GridView Control Events 11 . DataBinding—Raised immediately before GridView is bound to its data source. . DataBound—Raised immediately after GridView is bound to its data source. . RowCreated—Raised when each row in GridView is created. . RowDataBound—Raised when each row in GridView is bound to data. Second, the GridView control includes the following set of events raised when you edit records: . RowCommand—Raised when an event is raised by a control contained in GridView. . RowUpdating—Raised immediately before GridView updates a record. . RowUpdated—Raised immediately after GridView updates a record. . RowDeleting—Raised immediately before GridView deletes a record. . RowDeleted—Raised immediately after GridView deletes a record. . RowCancelingEdit—Raised when you cancel updating a record. Finally, the GridView control supports the following events related to sorting, selecting, and paging: . PageIndexChanging—Raised immediately before the current page changes. . PageIndexChanged—Raised immediately after the current page changes. . Sorting—Raised immediately before sorting. . Sorted—Raised immediately after sorting. . SelectedIndexChanging—Raised immediately before a row is selected. . SelectedIndexChanged—Raised immediately after a row is selected. In this section, you learn how to handle the RowDataBound event (my favorite event included with the GridView control) to create GridView special effects. You learn how to handle the RowDataBound event to highlight particular rows and show column summaries, and create nested Master/Detail forms. Highlighting GridView Rows Imagine that you want to highlight particular rows in GridView. For example, when displaying a table of sales totals, you might want to highlight the rows in which the sales are greater than a certain amount. You can modify the appearance of individual rows in a GridView control by handling the RowDataBound event. For example, the page in Listing 11.28 displays every movie that has a box office total greater than $300,000.00 with a yellow background color (see Figure 11.20). From the Library of Wow! eBook ptg 548 CHAPTER 11 Using the GridView Control LISTING 11.28 HighlightRows.aspx <%@ Page Language=”C#” %> <!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.1//EN” “http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd”> <script runat=”server”> protected void grdMovies_RowDataBound(object sender, GridViewRowEventArgs e) { if (e.Row.RowType == DataControlRowType.DataRow) { decimal boxOfficeTotals = (decimal)DataBinder.Eval(e.Row.DataItem, “BoxOfficeTotals”); if (boxOfficeTotals > 300000000) e.Row.BackColor = System.Drawing.Color.Yellow; } } </script> <html xmlns=”http://www.w3.org/1999/xhtml” > <head id=”Head1” runat=”server”> <title>Highlight Rows</title> </head> FIGURE 11.20 Highlighting rows in the GridView control. From the Library of Wow! eBook ptg 549 Working with GridView Control Events 11 <body> <form id=”form1” runat=”server”> <div> <asp:GridView id=”grdMovies” DataSourceID=”srcMovies” OnRowDataBound=”grdMovies_RowDataBound” AutoGenerateColumns=”false” Runat=”server”> <Columns> <asp:BoundField DataField=”Title” HeaderText=”Title” /> <asp:BoundField DataField=”BoxOfficeTotals” DataFormatString=”{0:c}” HtmlEncode=”false” HeaderText=”Box Office Totals” /> </Columns> </asp:GridView> <asp:SqlDataSource id=”srcMovies” ConnectionString=”<%$ ConnectionStrings:Movies %>” SelectCommand=”SELECT * FROM Movies” Runat=”server” /> </div> </form> </body> </html> In Listing 11.28, the grdMovies_RowDataBound() method is executed when GridView renders each of its rows (including its header and footer). The second parameter passed to this event handler is an instance of the GridViewRowEventArgs class. This class exposes a GridViewRow object that represents the row being bound. The GridViewRow object supports several useful properties (this is not a complete list): . Cells—Represents the collection of table row cells associated with the row being bound. . DataItem—Represents the data item associated with the row being bound. . DataItemIndex—Represents the index of the data item in its DataSet associated with the row being bound. From the Library of Wow! eBook ptg 550 CHAPTER 11 Using the GridView Control . RowIndex—Represents the index of the row being bound. . RowState—Represents the state of the row being bound. Possible values are Alternate, Normal, Selected, and Edit. Because these values can be combined (for example, RowState can be Alternate Edit), use a bitwise comparison RowState. . RowType—Represents the type of row being bound. Possible values are DataRow, Footer, Header, NullRow, Pager, and Separator. In Listing 11.28, the RowType property verifies that the row is DataRow (not a header row or some other type of row). The DataItem property retrieves the database record associated with the row. The DataBinder.Eval() method retrieves the value of the BoxOfficeColumn. Displaying Column Summaries Imagine that you want to display a column total at the bottom of a column. In that case, you can handle the GridView RowDataBound event to sum the values in a column and display the summary in the column footer. For example, the page in Listing 11.29 contains a GridView control that displays a summary column representing the total box office sales of all movies (see Figure 11.21). FIGURE 11.21 Displaying a column summary. From the Library of Wow! eBook ptg 551 Working with GridView Control Events 11 LISTING 11.29 SummaryColumn.aspx <%@ Page Language=”C#” %> <!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.1//EN” “http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd”> <script runat=”server”> private decimal _boxOfficeTotalsTotal = 0; protected void grdMovies_RowDataBound(object sender, GridViewRowEventArgs e) { if (e.Row.RowType == DataControlRowType.DataRow) { decimal boxOfficeTotals = (decimal)DataBinder.Eval(e.Row.DataItem, “BoxOfficeTotals”); _boxOfficeTotalsTotal += boxOfficeTotals; } if (e.Row.RowType == DataControlRowType.Footer) { Label lblSummary = (Label)e.Row.FindControl(“lblSummary”); lblSummary.Text = String.Format(“Total: {0:c}”, _boxOfficeTotalsTotal); } } </script> <html xmlns=”http://www.w3.org/1999/xhtml” > <head id=”Head1” runat=”server”> <title>Summary Column</title> </head> <body> <form id=”form1” runat=”server”> <div> <asp:GridView id=”grdMovies” DataSourceID=”srcMovies” OnRowDataBound=”grdMovies_RowDataBound” AutoGenerateColumns=”false” ShowFooter=”true” Runat=”server”> <Columns> <asp:BoundField DataField=”Title” HeaderText=”Title” /> <asp:TemplateField HeaderText=”Box Office Totals”> <ItemTemplate> <%# Eval(“BoxOfficeTotals”, “{0:c}”) %> From the Library of Wow! eBook ptg 552 CHAPTER 11 Using the GridView Control </ItemTemplate> <FooterTemplate> <asp:Label id=”lblSummary” Runat=”server” /> </FooterTemplate> </asp:TemplateField> </Columns> </asp:GridView> <asp:SqlDataSource id=”srcMovies” ConnectionString=”<%$ ConnectionStrings:Movies %>” SelectCommand=”SELECT * FROM Movies” Runat=”server” /> </div> </form> </body> </html> The GridView control uses a TemplateField to represent the BoxOfficeTotals column. The TemplateField includes a <FooterTemplate> that contains a Label control. The grdMovies_RowDataBound() method displays the total of the box office totals in this Label control. Displaying Nested Master/Details Forms You also can handle the RowDataBound event to create nested Master/Details forms. The page in Listing 11.30 displays a list of movie categories and displays a list of matching movies under each category (see Figure 11.22). From the Library of Wow! eBook ptg 553 Working with GridView Control Events 11 LISTING 11.30 NestedMasterDetail.aspx <%@ Page Language=”C#” %> <!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.1//EN” “http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd”> <script runat=”server”> protected void grdMovieCategories_RowDataBound(object sender, ➥GridViewRowEventArgs e) { if (e.Row.RowType == DataControlRowType.DataRow) { int categoryId = (int)DataBinder.Eval(e.Row.DataItem,”Id”); SqlDataSource srcMovies = (SqlDataSource)e.Row.FindControl(“srcMovies”); srcMovies.SelectParameters[“CategoryId”].DefaultValue = categoryId.ToString(); } } </script> <html xmlns=”http://www.w3.org/1999/xhtml” > <head id=”Head1” runat=”server”> <style type=”text/css”> FIGURE 11.22 Displaying a nested Master/Detail form. From the Library of Wow! eBook . ptg 544 CHAPTER 11 Using the GridView Control LISTING 11.27 ShowTemplateField.aspx <%@ Page Language=”C#” %> <!DOCTYPE html PUBLIC -/ /W3C//DTD XHTML 1.1//EN” “http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd”>. Control </ItemTemplate> <FooterTemplate> < ;asp: Label id=”lblSummary” Runat=”server” /> </FooterTemplate> < /asp: TemplateField> </Columns> < /asp: GridView> < ;asp: SqlDataSource. /> </EditItemTemplate> < /asp: TemplateField> < ;asp: TemplateField HeaderText=”Category”> <ItemTemplate> <%# Eval(“Name”) %> </ItemTemplate> <EditItemTemplate> < ;asp: DropDownList id=”ddlCategory” DataSourceID=”srcMovieCategories”