An <asp:DataGrid> control is designed to work with database tables and other relational data sources. It is very similar in use to a GridView control, which was introduced as replacement for the DataGrid. The DataGrid includes features for editing of databases as well as for their display. The present focus is on using the control for presentation of information. Its basic layout and formatting options are shown below.
<asp:DataGrid id="id" Runat="Server" AllowPaging="False|True" AllowSorting="False|True" AutoGenerateColumns="False|True" BackImageUrl="url" Caption="string" CaptionAlign="Top|Bottom|Left|Right|NotSet" CellPadding="n" CellSpacing="n" DataSourceID="id GridLines="Both|Horizontal|Vertical|None" HorizontalAlign="Left|Center|Right|Justify|NotSet" OnSortCommand="subprogram" PageButtonCount="n" PageSize="n" ShowHeader="False|True" ShowFooter="False|True" PagerStyle-Mode="NextPrev|NumericPages" PagerStyle-NextPageText="string" PagerStyle-PageButtonCount="n" PagerStyle-Position="Top|Bottom|TopAndBottom" PagerStyle-PreviousPageText="string" AlternatingItemStyle-property="value"... HeaderStyle-property="value"... ItemStyle-property="value"... FooterStyle-property="value"... property="value"... > <Columns> <asp:BoundColumn DataField="field" DataFormatString="{string}" FooterText="string" HeaderImageUrl="url" HeaderText="string" HtmlEncode="False|True" ReadOnly="False|True" SortExpression="field" FooterStyle-property="value" HeaderStyle-property="value" ItemStyle-property="value" /> <asp:HyperLinkColumn DataNavigateUrlField="field" DataNavigateUrlFormatString="{string}" DataTextField="field" DataTextFormatString="{string}" FooterText="string" HeaderImageUrl="url" HeaderText="string" NavigateUrl="url" SortExpression="field" Target="_blank|_search|_self|_top|_parent|framename" Text="string" FooterStyle-property="value" HeaderStyle-property="value" ItemStyle-property="value" /> <asp:TemplateColumn FooterText="string" HeaderImageUrl="url" HeaderText="string" SortExpression="field" FooterStyle-property="value"... HeaderStyle-property="value"... ItemStyle-property="value"... > <HeaderTemplate> XHTML and binding expressions </HeaderTemplate> <ItemTemplate> XHTML and binding expressions </ItemTemplate> <FooterTemplate> XHTML and binding expressions </FooterTemplate> </asp:TemplateColumn> </Columns> </asp:DataGrid>
The <asp:DataGrid> control presents information in a table. It can automatically generates as many columns as there are data fields retrieved from the data source, or selected columns can be formatted for display. It generates as many rows as there are records in the retrieved recordset. Server style properties can be applied to the table as a whole and/or to specified rows and columns. Like the GridView, the DataGrid permits sorting and paging.
Creating a DataGrid Display
It requires very little declarative code, and no scripting, to produce a basic DataGrid table. The following table presents selected information from the BooksDB.mdb database. It is produced with an AccessDataSource and DataGrid control using default formatting.
<asp:AccessDataSource id="BookSource" Runat="Server" DataFile="../Databases/BooksDB.mdb" SelectCommand="SELECT BookID, BookType, BookTitle, BookAuthor, BookPrice, BookQty FROM Books ORDER BY BookID"/> <asp:DataGrid id="BookGrid" Runat="Server" DataSourceID="BookSource"/>
As many columns of data are produced as there are fields from the data source. A row of column headings is generated from the field names in the data source. As you can see, a DataGrid, like a GridView, is a quick and efficient way to display a data source in tabular format.
Styling a DataGrid
Formatting of a DataGrid takes place through various server style properties applied to the table as a whole or to selected rows. Specifying one of the common style properties and values applies it to the table; prefixing the property setting with HeaderStyle-, ItemStyle-, AlternatingItemStyle-, or FooterStyle- applies the style property to the identified section of the table. In the following example, Caption, CellPadding, BorderStyle, BorderWidth, BackColor, and ForeColor style properties are applied to the grid. Different colors and fonts are applied to the header row and to alternating detail rows.
<asp:AccessDataSource id="BookSource" Runat="Server" DataFile="../Databases/BooksDB.mdb" SelectCommand="SELECT BookID, BookType, BookTitle, BookPrice, BookQty FROM Books ORDER BY BookID"/> <asp:DataGrid id="BookGrid" DataSourceID="BookSource" Runat="Server" Caption="<b>Table 1. Books</b>" CaptionAlign="Left" CellPadding="2" BorderStyle="Ridge" BorderWidth="5" BackColor="#F0F0F0" ForeColor="#000000" HeaderStyle-BackColor="#707070" HeaderStyle-ForeColor="#FFFFFF" HeaderStyle-Font-Names="Verdana" HeaderStyle-Font-Size="8pt" HeaderStyle-Font-Bold="True" ItemStyle-Font-Names="Verdana" ItemStyle-Font-Size="8pt" AlternatingItemStyle-BackColor="#A0A0A0" AlternatingItemStyle-ForeColor="#FFFFFF/>
You should notice that styling the rows of a DataGrid uses ItemStyle and AlternatingItemStyle properties. These differ from the GridView, which uses RowStyle and AlternatingRowStyle properties. Otherwise, style properties are identical for the two controls.
Selecting Columns for Display
A DataGrid permits selections of data columns for display, overriding the default setting that maps all data source fields to the control. In order to select which columns to display, first specify AutoGenerateColumns="False" for the grid. Then include a <Columns> section in the control. Within this section an <asp:BoundColumn> control or <asp:HyperLinkColumn> control is added for each column to be displayed. Note that these bound columns differ from the GridView, which uses <asp:BoundField> and <asp:HyperLinkField> controls. Otherwise, property settings for these controls are virtually identical to those used in a GridView.
<asp:AccessDataSource id="BookSource" Runat="Server" DataFile="../Databases/BooksDB.mdb" SelectCommand="SELECT * FROM Books WHERE BookType = 'Graphics' ORDER BY BookId"/> <asp:DataGrid id="BookGrid" DataSourceID="BookSource" Runat="Server" AutoGenerateColumns="False" ShowFooter="True" Caption="<b>Graphics Books</b>" CellPadding="3" BorderStyle="Ridge" BorderWidth="5" BackColor="#F0F0F0" ForeColor="#000000" HeaderStyle-BackColor="#707070" HeaderStyle-ForeColor="#FFFFFF" HeaderStyle-Font-Names="Verdana" HeaderStyle-Font-Size="10pt" HeaderStyle-Font-Bold="True" HeaderStyle-HorizontalAlign="Center" ItemStyle-Font-Names="Verdana" ItemStyle-Font-Size="10pt" AlternatingItemStyle-BackColor="#C0C0C0" AlternatingItemStyle-ForeColor="#FFFFFF" FooterStyle-BackColor="#707070" FooterStyle-ForeColor="#FFFFFF"> <Columns> <asp:HyperLinkColumn HeaderText="ID" DataTextField="BookID" DataNavigateUrlField="BookID" DataNavigateUrlFormatString="../eCommerce/BookPictures/{0}.jpg" Target="_blank" FooterText="*In stock" FooterStyle-Font-Size="7pt" FooterStyle-BorderWidth="0"/> <asp:BoundColumn DataField="BookTitle" HeaderText="Title" FooterStyle-BorderWidth="0"/> <asp:BoundColumn DataField="BookPrice" HeaderText="Price" DataFormatString="{0:C}" ItemStyle-HorizontalAlign="Right" FooterStyle-BorderWidth="0"/> <asp:BoundColumn DataField="BookQty" HeaderText="Qty*" DataFormatString="{0:D}" ItemStyle-HorizontalAlign="Right" FooterStyle-BorderWidth="0"/> </Columns> </asp:DataGrid>
Numeric and string formats for a bound column are specified in the DataFormatString, DataTextFormatString, and DataNavigateUrlFormatString properties. These string values use the formatting codes described previously for the GridView control.
Template Columns
In addition to bound data columns, a DataGrid supports template columns. As in the case of the GridView, Repeater, and DataList controls, XHTML tags, server controls, and binding expressions can be added to <HeaderTemplate>, <ItemTemplate>, and <FooterTemplate> sections to override default layouts. Template columns appear inside the <asp:Columns> section of the DataGrid and are identified by an <asp:TemplateColumn> control. Note that this differs from the <asp:TemplateField> control used in a GridView. Bound data values in a template column are specified with the standard binding expression: <%# Eval("field") %>.
In the following DataGrid a TemplateColumn gives the inventory amounts of selected books from the BooksDB.mdb database. Other TemplateColumns display book titles, checkboxes for on-sale items, and book images.
<asp:AccessDataSource id="BookSource" Runat="Server" DataFile="../Databases/BooksDB.mdb" SelectCommand="SELECT * FROM Books WHERE BookType = 'Graphics' ORDER BY BookID"/> <asp:DataGrid id="BookGrid" DataSourceID="BookSource" Runat="Server" AutoGenerateColumns="False" Caption="<b>Inventory Valuation - Graphics Books</b>" CellPadding="3" HeaderStyle-HorizontalAlign="Center" HeaderStyle-BackColor="#707070" HeaderStyle-ForeColor="#FFFFFF" HeaderStyle-Font-Bold="True" HeaderStyle-Font-Name="Verdana" HeaderStyle-Font-Size="10pt" ItemStyle-Font-Name="Verdana" ItemStyle-Font-Size="10pt"> <Columns> <asp:HyperLinkColumn HeaderText="ID" DataTextField="BookID"/> <asp:BoundColumn DataField="BookTitle" HeaderText="Title"/> <asp:BoundColumn DataField="BookPrice" HeaderText="Price" ItemStyle-HorizontalAlign="Right" DataFormatString="{0:N2}"/> <asp:BoundColumn DataField="BookQty" HeaderText="Qty" ItemStyle-HorizontalAlign="Right"/> <asp:TemplateColumn ItemStyle-HorizontalAlign="Right"> <HeaderTemplate> Amount </HeaderTemplate> <ItemTemplate> <asp:Label id="Amount" Runat="Server" Text='<%# String.Format("{0:C}", Eval("BookPrice") * Eval("BookQty")) %>'/> </ItemTemplate> </asp:TemplateColumn> <asp:TemplateColumn ItemStyle-HorizontalAlign="Center"> <HeaderTemplate> Sale </HeaderTemplate> <ItemTemplate> <asp:CheckBox Checked='<%# Eval("BookSale") %>' Runat="Server"/> </ItemTemplate> </asp:TemplateColumn> <asp:TemplateColumn ItemStyle-HorizontalAlign="Center"> <HeaderTemplate> Picture </HeaderTemplate> <ItemTemplate> <asp:Image Width="40" Runat="Server" AlternateText='<%# "Picture of " & Eval("BookID") %>' ImageUrl='<%# "../BookPictures/" & Eval("BookID") & ".jpg" %>'/> </ItemTemplate> </asp:TemplateColumn> </Columns> </asp:DataGrid>
BoundColumns are used to display the BookID, BookTitle, BookPrice, and BookQty fields directly from the available recordset. A TemplateColumn is needed for the amount column, which displays the price field multiplied times the quantity field for each record. A TemplateColumn encloses a CheckBox control for the BookSale field; and a TemplateColumn is used to display graphic images with an embedded <asp:Image> control.
DataGrid Sorting and Paging
Unlike the Repeater and DataList, a DataGrid supports sorting and paging of the displayed recordset. These features are demonstrated in the following example. Pages are called up by the page numbers at the bottom of the grid; sorting in ascending sequence (only) takes place by clicking column headings.
DataGrid Sorting
Sorting takes place by coding AllowSorting="True" as a DataGrid property setting. Each BoundColumn whose heading serves as a sort field is given the property setting SortExpression="field" where field is the name of a database field on which the column is sorted. Normally the field name is the same as the DataField property for the column.
A TemplateColumn heading can trigger sorting by including a SortExpression property. Also, it is necessary that the TemplateColumn also include the HeaderText property setting. That is, a HeaderTemplate should not appear in the TemplateColumn. Rather, the column heading and sort expression should be coded in the format: <TemplateColumn HeaderText="heading" SortExpression="field">. Again, the sort expression field must be one of the database fields.
After the AllowSorting property is set for the DataGrid, and one or more SortExpression properties are coded for the column headings, the DataGrid must include an OnSortCommand event handler to call a subprogram when one of the sort headings is clicked. This subprogram determines which of the sort expression fields to sort on, and then rebinds the DataGrid with this sorted recordset.
Code for the above DataGrid is shown below along with the Sort_Grid subprogram that is called when a sort heading is clicked. Additional script relates to DataGrid paging and is explained below.
<SCRIPT Runat="Server"> Sub Sort_Grid (Src As Object, Args As DataGridSortCommandEventArgs) Dim SQLString As String SQLString = "SELECT * FROM Books ORDER BY " & Args.SortExpression BookSource.SelectCommand = SQLString BookGrid.DataBind() End Sub Sub Change_Page (Src As Object, Args As DataGridPageChangedEventArgs) BookGrid.CurrentPageIndex = Args.NewPageIndex BookGrid.DataBind() End Sub </SCRIPT> <form Runat="Server"> <asp:AccessDataSource id="BookSource" Runat="Server" DataFile="../Databases/BooksDB.mdb" SelectCommand="SELECT * FROM Books ORDER BY BookID"/> <asp:DataGrid id="BookGrid" DataSourceID="BookSource" Runat="Server" AutoGenerateColumns="False" AllowSorting="True" OnSortCommand="Sort_Grid" AllowPaging="True" PageSize="4" PagerStyle-Mode="NumericPages" OnPageIndexChanged="Change_Page" Caption="<b>Book Valuation</b>" CellPadding="3" HeaderStyle-HorizontalAlign="Center" HeaderStyle-BackColor="#707070" HeaderStyle-ForeColor="#FFFFFF" HeaderStyle-Font-Bold="True" HeaderStyle-Font-Size="10pt" ItemStyle-Font-Size="9pt" ItemStyle-VerticalAlign="Top"> <Columns> <asp:BoundColumn HeaderText="ID" DataField="BookID" SortExpression="BookID"/> <asp:BoundColumn DataField="BookTitle" HeaderText="Title" SortExpression="BookTitle"/> <asp:BoundColumn DataField="BookPrice" HeaderText="Price" ItemStyle-HorizontalAlign="Right" DataFormatString="{0:N2}" SortExpression="BookPrice"/> <asp:BoundColumn DataField="BookQty" HeaderText="Qty" ItemStyle-HorizontalAlign="Right" SortExpression="BookQty"/> <asp:TemplateColumn ItemStyle-HorizontalAlign="Right"> <HeaderTemplate> Amount </HeaderTemplate> <ItemTemplate> <asp:Label id="Amount" Runat="Server" Text='<%# String.Format("{0:N}", Eval("BookPrice") * Eval("BookQty")) %>'/> </ItemTemplate> </asp:TemplateColumn> <asp:TemplateColumn HeaderText="Description" SortExpression="BookTitle"> <ItemTemplate> <asp:Panel ScrollBars="Auto" Width="180" Height="50" Runat="Server"> <asp:Label Font-Size="8" Style="line-height:9pt" Runat="Server" Text='<%# Eval("BookDescription") %>'/><br/> </asp:Panel> </ItemTemplate> </asp:TemplateColumn> <asp:TemplateColumn ItemStyle-HorizontalAlign="Center"> <HeaderTemplate> Sale </HeaderTemplate> <ItemTemplate> <asp:CheckBox Checked='<%# Eval("BookSale") %>' Runat="Server"/> </ItemTemplate> </asp:TemplateColumn> <asp:TemplateColumn ItemStyle-HorizontalAlign="Center"> <HeaderTemplate> Picture </HeaderTemplate> <ItemTemplate> <asp:Image Width="40" Runat="Server" AlternateText='<%# "Picture of " & Eval("BookID") %>' ImageUrl='<%# "../BookPictures/" & Eval("BookID") & ".jpg" %>'/> </ItemTemplate> </asp:TemplateColumn> </Columns> </asp:DataGrid>
When any of the sort headings is clicked, the DataGrid's OnSortCommand event handler calls the Sort_Grid subprogram. Notice the subprogram's signature has the argument DataGridPageChangedEventArgs. An argument passed to the subprogram is the SortExpression value of the heading that was clicked. Therefore, the reference Args.SortExpression is the name of a database field for sorting. The subprogram uses this argument to compose an SQL SELECT statement to return a recordset sorted on this field. This statement is assigned to the AccessDataSource for the DataGrid and the sorted recordset is bound to the grid.
In the current example, sorting takes place in ascending sequence. The script can be modified to alternate between ascending and descending sequence as is done in a GridView. This amounts to keeping track of the sort order between page post-backs and reversing the setting. In the following modified script, a View State variable records the initial sort order (ascending) when the page first loads. This order is given by the SQL clause (" ASC") that is appended to the the SELECT statement's ORDER BY clause to control sort order. In the Sort_Grid subprogram, this View State variable is appended to the statement. Then, ViewState("SortOrder") is reversed to " DESC" or back to " ASC" on each visit to the subprogram.
Sub Page_Load If Not Page.IsPostBack Then ViewState("SortOrder") = " ASC" End If End Sub Sub Sort_Grid (Src As Object, Args As DataGridSortCommandEventArgs) Dim SQLString As String SQLString = "SELECT * FROM Books ORDER BY " & _ Args.SortExpression & ViewState("SortOrder") BookSource.SelectCommand = SQLString BookGrid.DataBind() If ViewState("SortOrder") = " ASC" Then ViewState("SortOrder") = " DESC" Else ViewState("SortOrder") = " ASC" End If End Sub
DataGrid Paging
Paging takes place by adding the AllowPaging="True" property to the DataGrid. The page size is given in the PageSize property. The DataGrid also must name a subprogram to call when a paging button is clicked by including an OnPageIndexChanged event handler. The following partial code shows these settings for the previous DataGrid.
<asp:DataGrid id="BookGrid" DataSourceID="BookSource" Runat="Server" AutoGenerateColumns="False" AllowSorting="True" OnSortCommand="Sort_Grid" AllowPaging="True" PageSize="4" OnPageIndexChanged="Change_Page" PagerStyle-Mode="NumericPages" ...
Optional stylings for page buttons include its Mode (default NextPrev buttons or NumericPages buttons), its Position (Top, Bottom, or TopAndBottom), and its NextPageText and PreviousPageText properties to override the default text labels used for Next and Prev buttons. These stylings are made with the PagerStyle- prefix to the property settings.
When a DataGrid permits paging, its displayed recordset is divided into PageSize subsets of records, each identified by an index number. A clicked paging button passes along its index number reference to the OnPageIndexChanged subprogram for display of that particular subset of records. This subprogram, named Change_Page in the current example, sets the page index for the recordset and rebinds it to the DataGrid.
Sub Change_Page (Src As Object, Args As DataGridPageChangedEventArgs) BookGrid.CurrentPageIndex = Args.NewPageIndex BookGrid.DataBind() End Sub
Paging buttons call a subprogram with the argument DataGridPageChangedEventArgs whose NewPageIndex property is the page index passed by the buttons. This index is assigned as the CurrentPageIndex of the DataGrid, and binding of the grid displays this subset of records.