在頁眉添加圖片和文字
The HeaderImageUrl property displays an image for a header. The image is not displayed in the background, so you cannot combine the HeaderImageUrl property with the HeaderText property to display both an image and text. If you want to display both an image and text in a header, you need to assign the HTML tags for an image to the HeaderText property like this: HeaderText="<img src=myImage.Gif>Titles"
模板列 Sub Page_Load
Dim conPubs As SqlConnection
Dim cmdSelect As SqlCommand
conPubs = New SqlConnection( "Server=localhost;UID=sa;PWD=secret;Database=Pubs" )
cmdSelect = New SqlCommand( "Select * From Authors", conPubs )
conPubs.Open()
dgrdAuthors.DataSource = cmdSelect.ExecuteReader()
dgrdAuthors.DataBind()
conPubs.Close()
End Sub
<html>
<head><title>DataGridTemplate.aspx</title></head>
<body>
<form Runat="Server">
<asp:DataGrid
ID="dgrdAuthors"
AutoGenerateColumns="False"
EnableViewState="False"
ShowHeader="False"
CellPadding="10"
Runat="Server">
<Columns>
<asp:BoundColumn
DataField="au_lname" />
<asp:TemplateColumn>
<itemTemplate>
<table>
<tr>
<td>Phone:</td>
<td><%# Container.DataItem( "phone" )%></td>
</tr>
<tr>
<td>City:</td>
<td><%# Container.DataItem( "city" )%></td>
</tr>
</table>
</itemTemplate>
</asp:TemplateColumn>
</Columns>
</asp:DataGrid>
</form>
</body>
</html>
The C# version of this code can be found on the CD-ROM.
Figure 11.11. Using a TemplateColumn.
Notice that templates work differently when used with a DataGrid than when used with either a Repeater or DataList control. When you create templates for a Repeater or DataList, the template formats rows of data displayed by the control. When a template is used with a DataGrid, in contrast, the template formats a single column, not the whole row.Sorting Columns in a DataGrid Control
在DataGrid中排序
The DataGrid control has built-in support for sorting columns. You can enable sorting for all the columns in a DataGrid or enable sorting for only particular columns.
To enable sorting for all the columns in a DataGrid, set the AllowSorting property to True and associate a subroutine with the SortCommand event.
Listing 11.17 DataGridSort.aspx
<%@ Import Namespace="System.Data.SqlClient" %>
<Script Runat="Server">
Sub Page_Load
If Not IsPostBack Then
BindDataGrid( "Title" )
End If
End Sub
Sub BindDataGrid( strSortField As String )
Dim conPubs As SqlConnection
Dim cmdSelect As SqlCommand
conPubs = New SqlConnection( "Server=localhost;UID=sa;PWD=secret;Database=Pubs" )
cmdSelect = New SqlCommand( "Select * From Titles Order By " & strSortField, conPubs )
conPubs.Open()
dgrdTitles.DataSource = cmdSelect.ExecuteReader()
dgrdTitles.DataBind()
conPubs.Close()
End Sub
Sub dgrdTitles_SortCommand( s As Object, e As DataGridSortCommandEventArgs )
BindDataGrid( e.SortExpression )
End Sub
</Script>
<html>
<head><title>DataGridSort.aspx</title></head>
<body>
<form Runat="Server">
<asp:DataGrid
ID="dgrdTitles"
AllowSorting="True"
OnSortCommand="dgrdTitles_SortCommand"
CellPadding="10"
Runat="Server" />
</form>
</body>
</html>
You can enable and disable sorting for particular columns by using the SortExpression property. Sorting on certain columns, such as ProductID, might not make any sense. For example, the DataGrid in Listing 11.18 enables you to sort the first two columns, but not the last (see Figure 11.16).
Listing 11.18 DataGridSortExpression.aspx
<%@ Import Namespace="System.Data.SqlClient" %>
<Script Runat="Server">
Sub Page_Load
If Not isPostBack Then
BindDataGrid( "Title" )
End If
End Sub
Sub BindDataGrid( strSortField As String )
Dim conPubs As SqlConnection
Dim cmdSelect As SqlCommand
conPubs = New SqlConnection( "Server=localhost;UID=sa;PWD=secret;Database=Pubs" )
cmdSelect = New SqlCommand( "Select * From Titles Order By " & strSortField, conPubs )
conPubs.Open()
dgrdTitles.DataSource = cmdSelect.ExecuteReader()
dgrdTitles.DataBind()
conPubs.Close()
End Sub
Sub dgrdTitles_SortCommand( s As Object, e As DataGridSortCommandEventArgs )
BindDataGrid( e.SortExpression )
End Sub
</Script>
<html>
<head><title>DataGridSortExpression.aspx</title></head>
<body>
<form Runat="Server">
<asp:DataGrid
ID="dgrdTitles"
AllowSorting="True"
OnSortCommand="dgrdTitles_SortCommand"
AutoGenerateColumns="False"
CellPadding="10"
Runat="Server">
<Columns>
<asp:BoundColumn
DataField="Title"
HeaderText="Sort Titles"
SortExpression="title"/>
<asp:BoundColumn
HeaderText="Sort Price"
DataField="price"
DataFormatString="{0:c}"
SortExpression="price"/>
<asp:BoundColumn
DataField="Notes" />
</Columns>
</asp:DataGrid>
</form>
</body>
</html>
自定義分頁
When you use the method of paging through records discussed in the preceding section, all the records must be retrieved from the data source every time you navigate to a new page. So, if you are paging through a database table with 2 million records, those 2 million records must be retrieved into memory every time you move to a new page.
The custom paging solution you examine here makes a strong assumption about the contents of the database table with which it is used. This approach works only with database tables that have a column that uniquely indexes each database row. For example, it works with a table that has an identity column when the identity column is not missing any values.
CAUTION
If certain values are missing from the identity column, the DataGrid displays fewer records for some pages than others.
This custom paging approach is implemented in Listing 11.20.
Listing 11.20 DataGridCustomPaging.aspx
<%@ Import Namespace="System.Data.SqlClient" %>
<%@ Import Namespace="System.Data" %>
<Script Runat="Server">
Dim conNorthwind As SqlConnection
Dim strSelect As String
Dim intStartIndex As Integer
Dim intEndIndex As Integer
Sub Page_Load
Dim cmdSelect As SqlCommand
conNorthwind = New SqlConnection( "Server=localhost;UID=sa;PWD=secret;Database=Northwind" )
If Not IsPostBack Then
' Get Total Pages
strSelect = "Select Count(*) From Products"
cmdSelect = New SqlCommand( strSelect, conNorthwind )
conNorthwind.Open()
dgrdProducts.VirtualItemCount = ( cmdSelect.ExecuteScalar() / dgrdProducts.PageSize )
conNorthwind.Close()
BindDataGrid
End If
End Sub
Sub BindDataGrid
Dim dadProducts As SqlDataAdapter
Dim dstProducts As DataSet
intEndIndex = intStartIndex + dgrdProducts.PageSize
strSelect = "Select * From Products Where ProductID > @startIndex " _
& "And ProductID <= @endIndex Order By ProductID"
dadProducts = New SqlDataAdapter( strSelect, conNorthwind )
dadProducts.SelectCommand.Parameters.Add( "@startIndex", intStartIndex )
dadProducts.SelectCommand.Parameters.Add( "@endIndex", intEndIndex )
dstProducts = New DataSet
dadProducts.Fill( dstProducts )
dgrdProducts.DataSource = dstProducts
dgrdProducts.DataBind()
End Sub
Sub dgrdProducts_PageIndexChanged( s As Object, e As DataGridPageChangedEventArgs )
intStartIndex = ( e.NewPageIndex * dgrdProducts.PageSize )
dgrdProducts.CurrentPageIndex = e.NewPageIndex
BindDataGrid
End Sub
</Script>
<html>
<head><title>DataGridCustomPaging.aspx</title></head>
<body>
<form Runat="Server">
<asp:DataGrid
ID="dgrdProducts"
AllowPaging="True"
AllowCustomPaging="True"
PageSize="3"
OnPageIndexChanged="dgrdProducts_PageIndexChanged"
PagerStyle-Mode="NumericPages"
CellPadding="3"
Runat="Server" />
</form>
</body>
</html>
The page in Listing 11.20 enables you to page through the records in the Products database table three records at a time. (You can change the number of records displayed at a time by changing the value of the PageSize property.)
A count of the total number of records in the Products table is retrieved in the Page_Load subroutine. This value is assigned to the VirtualItemCount property of the DataGrid. The DataGrid control uses this property when rendering the paging links.
When you click a page number link, the dgrdProducts_PageIndexChanged subroutine is executed. This subroutine calculates the starting index of the record to display by multiplying the index of the selected page by the page size. The correct set of records is retrieved from the Products database table with this SQL statement:
Select * From Products Where ProductID > @startIndex
And ProductID <= @endIndex Order By ProductID"
This Select statement retrieves all the records that have a ProductID greater than the startIndex and less than or equal to the endIndex. The endIndex is calculated by adding the startIndex to the value of the PageSize property of the DataGrid.
The advantage of this approach to paging through records is that the only records retrieved from the database are the records displayed in the DataGrid. In other words, this approach works great with huge database tables.
Selecting Rows in a DataGrid Control
The page in Listing 11.21 contains two DataGrid controls. The first DataGrid lists categories and category descriptions, and the second DataGrid lists product information. When you select a category from the first DataGrid, the products in that category are displayed in the second DataGrid (see Figure 11.19).
Listing 11.21 DataGridMasterDetail.aspx
<%@ Import Namespace="System.Data.SqlClient" %>
<Script Runat="Server">
Sub Page_Load
If Not IsPostBack Then
BindMasterGrid
End If
End Sub
Sub BindMasterGrid
Dim conNorthwind As SqlConnection
Dim cmdSelect As SqlCommand
conNorthwind = New SqlConnection( "Server=localhost;UID=sa;PWD=secret;Database=Northwind" )
cmdSelect = New SqlCommand( "Select * From Categories", conNorthwind )
conNorthwind.Open()
dgrdCategories.DataSource = cmdSelect.ExecuteReader()
dgrdCategories.DataBind()
conNorthwind.Close()
End Sub
Sub BindDetailGrid( intCatID As Integer )
Dim conNorthwind As SqlConnection
Dim strSelect As String
Dim cmdSelect As SqlCommand
conNorthwind = New SqlConnection( "Server=localhost;UID=sa;PWD=secret;Database=Northwind" )
strSelect = "Select * From Products Where CategoryID=@catID"
cmdSelect = New SqlCommand( strSelect, conNorthwind )
cmdSelect.Parameters.Add( "@catID", intCatID )
conNorthwind.Open()
dgrdProducts.DataSource = cmdSelect.ExecuteReader()
dgrdProducts.DataBind()
conNorthwind.Close()
End Sub
Sub dgrdCategories_ItemCommand( s As Object, e As DataGridCommandEventArgs )
Dim intCatID As Integer
intCatID = dgrdCategories.DataKeys( e.Item.ItemIndex )
dgrdCategories.SelectedIndex = e.Item.ItemIndex
BindDetailGrid( intCatID )
End Sub
</Script>
<html>
<head><title>DataGridMasterDetail.aspx</title></head>
<body>
<form Runat="Server">
<asp:DataGrid
ID="dgrdCategories"
OnItemCommand="dgrdCategories_ItemCommand"
DataKeyField="CategoryID"
AutoGenerateColumns="False"
SelectedItemStyle-BackColor="LightGreen"
ShowHeader="False"
Runat="Server">
<Columns>
<asp:TemplateColumn>
<ItemTemplate>
<asp:LinkButton
Text='<%# Container.DataItem( "CategoryName" ) %>'
Runat="Server"/>
</ItemTemplate>
</asp:TemplateColumn>
<asp:BoundColumn DataField="Description" />
</Columns>
</asp:DataGrid>
<p>
<asp:DataGrid
ID="dgrdProducts"
HeaderStyle-BackColor="yellow"
Runat="Server" />
</form>
</body>
</html>
The C# version of this code can be found on the CD-ROM.
Figure 11.19. Selecting DataGrid rows.