DatagridGirl.com
2003 年 9 月
摘要: ASP.NET Datagrid 是 Web 開發人員可以使用的一個功能強大的控件。通過添加自定義列以便為用戶更準確地顯示數據,來學習如何增強該控件的功能。(本文包含一些指向英文站點的鏈接。)
適用于:
Microsoft? ASP.NET
下載本文的源代碼 。(請注意,在示例文件中,程序員的注釋使用的是英文,本文中將其譯為中文是為了便于讀者理解。)
目錄
簡介
重復使用的情況
DropDownList 方案
內置的 Datagrid 列
傳統方法:TemplateColumn 中的 DropDownList
所有列的基礎:DataGridColumn
可以重復使用的方法:創建 DropDownColumn
使用 DropDownColumn
小結
簡介
不得不承認,為 Microsoft? ASP.NET 編寫 Datagrid 代碼包括大量的重復工作。盡管我深受該控件的困擾,但我還是不斷尋找簡化這類任務的捷徑。誰都不愿意做重復的工作,對不對?為了擺脫這種煩人的工作,我們要將多個項目中的重復代碼封裝到一個可重復使用的程序包中。這才是面向對象的編程工作所要解決的問題,使用 Datagrid 也不例外。對于 Datagrid 控件來說,要實現該目的,需要將常用的代碼放到一個內置的列類型中(將在第一個示例中使用),然后創建一個可以在多個 Datagrid 對象中重復使用的自定義列類型。
本文介紹使用標準 TemplateColumn 在一個 Datagrid 列中使用 DropDownList 控件的過程,然后將該邏輯轉換為您的自定義 Datagrid 列類型,我稱其為 DropDownColumn 。已經為您創建了一些免費的 Datagrid 列,您可以到 MetaBuilders.com 下載所需的類型。
重復使用的情況
如果您的小組與許多組織一樣,已經將業務邏輯和/或數據訪問邏輯分成單獨的組件或組件集,而剩下的 ASP.NET 文件、ASPX 及其代碼只包含純粹的表示邏輯。(“純粹”是一個相對的詞語。)但是,即使是表示層的邏輯有時也會重復使用,這樣,下次某個用戶來到您門前說,“我想讓我的應用程序在‘財務’方面看起來與蘇茜的一樣”時,您可以重復使用“財務”應用程序的部分表示內容快速為其構建一個這樣的應用程序。您可能還想將一些邏輯打包,在 Web 上銷售或在您的 Web 站點分發。ASP.NET 使這一切比以往更容易實現,因為它使您可以創建自己的服務器控件,或從現有的類型導出列類型,從而獲得所需的功能。
DropDownList 方案
假設您正在本地 Microsoft SQL Server? 中編輯 Northwind 數據庫(或做其他工作),您想使您的用戶(我們稱之為 Ed,倉庫保管員)可以編輯 Orders 表。其中一個字段包含運輸信息 (ShipVia),Ed 要能夠修改該字段的信息。在顯示模式下,運輸公司應顯示為純文本。當 Ed 單擊 Edit(編輯)按鈕時,您不光要為他提供一個 TextBox 以編輯運輸方式代碼(1、2 或 3),還要為他提供一個包含可以選擇不同運輸公司的 DropDownList 。(因為 Ed 記不住哪個運輸公司對應哪個號碼,所以,DropDownList 方案可以幫助他解決這個問題。)
圖 1:選擇運輸公司
內置的 Datagrid 列
了解問題的大概情況后,現在我們后退一步,看一下 ASP.NET 中構建的 5 種 Datagrid 列類型及其父類型 DataGridColumn 。
- BoundColumn 。這是文本字段的標準顯示。它顯示為純文本,但是當 Datagrid 處于“編輯”模式時,它將轉換為 TextBox 。還可以選擇格式化選項。
- HyperlinkColumn 。用于顯示文本數據,還代表一個 Web 地址 (URL)。URL 可以與顯示文本相同,也可以不同,它們都可以單獨設置。它顯示為 <a href=...> 標記。
- ButtonColumn 。它使用戶能夠按行與網格進行交互。它可以顯示為超鏈接 LinkButton (<a href=...>) 或 Pushbutton (<input type="button">)。單擊該按鈕時將觸發 PostBack,而在 Datagrid 上觸發 ItemCommand 事件。
- EditCommandColumn 。它與 ButtonColumn 類似,但是它自動創建用于編輯 Datagrid 、取消或提交更改的按鈕。觸發 ItemCommand 事件,以及所單擊按鈕的特定事件: EditCommand 、 CancelCommand 或 UpdateCommand 。
- TemplateColumn 。用于完全控制顯示給用戶的控件,分為多種模板,例如 ItemTemplate 和 EditItemTemplate 。任何 ASP.NET 或 HTML 控件或控件組都可以放置在這些模板中。
注意: 直接使用這些列類型之前,請關閉 AutoGenerateColumns(運行時自動生成列)。然后,您可以在屬性生成器中使用這些列類型,或者直接在 ASPX 文件的 HTML 代碼中使用。
圖 2:從 DataGridColumn 中繼承的 5 種內置列
盡管這些列類型非常有用,它們不過是了解 Datagrid 列內容的開始。
傳統方法:TemplateColumn 中的 DropDownList
在研究如何創建新列類型之前,首先讓我們看一下如何通過直接在 TemplateColumn 內使用 DropDownList 解決下拉列表的問題,而不用自定義列。 ItemTemplate 將只包含表示當前值的純文本表示,而 EditItemTemplate 包含一個需要在運行時管理的 <asp:DropDownList> 控件。
<asp:DataGrid id="DataGrid1" runat="server" CssClass="grid" AutoGenerateColumns="False"> <Columns> <asp:EditCommandColumn EditText="Edit" CancelText="Cancel" UpdateText="Update" /> <asp:BoundColumn DataField="OrderID" ReadOnly="True" HeaderText="Order ID" /> <asp:BoundColumn DataField="ShipName" HeaderText="Ship to" ReadOnly="True" /> <asp:BoundColumn DataField="ShipCountry" HeaderText="Country" ReadOnly="True" /> <asp:TemplateColumn HeaderText="Ship Method"> <ItemTemplate> <%#Container.DataItem("ShipVia")%> </ItemTemplate> <EditItemTemplate> <asp:DropDownList runat="server" ID="Dropdownlist1"/> </EditItemTemplate> </asp:TemplateColumn> </Columns> </asp:DataGrid>
綁定 Datagrid 的代碼:
Sub BindGrid() Dim SQL As String = "SELECT OrderID, ShipName, ShipCountry, ShipVia FROM Orders" Dim DA As SqlDataAdapter = New SqlDataAdapter(SQL, ConnStr) Dim DS As New DataSet DA.Fill(DS, "Orders") DataGrid1.DataSource = DS.Tables("Orders").DefaultView DataGrid1.DataBind() End Sub
當前編輯的項目是在觸發 Datagrid 的 ItemDataBound 事件時綁定到 DropDownList 的。使用 ItemDataBound 事件時,請檢查當前項目的 ListItemType ,否則您可能會發現您正在使用 HeaderItem 或其他不適用的項目類型。為 EditItem 引用 DropDownList 控件。在下面的代碼中,我直接使用單元格控件集進行說明(為了與后面的示例保持一致),但是,您可以采用簡單的方法,直接為 DropDownList 控件指定 ID,并使用 Datagrid 項目的 FindControl 方法定位控件引用。由于 Datagrid 被綁定到 DataTable 的默認視圖,而該視圖的元素屬于 DataRowView 類型,所以您可以將當前項目的 DataItem 屬性轉換為一個 DataRowView 實例。這樣,您可以按字段名直接引用 DataItem 中的字段。使用這種方法,將“ShipVia”的當前值保存到該記錄中,并使用它選擇相應的下拉列表項。
Private Sub DataGrid1_ItemDataBound(ByVal sender As Object, _ ByVal e As System.Web.UI.WebControls.DataGridItemEventArgs) _ Handles DataGrid1.ItemDataBound If e.Item.ItemType = ListItemType.EditItem Then Dim DRV As DataRowView = CType(e.Item.DataItem, DataRowView) Dim CurrentShip As String = DRV("ShipVia") Dim DDL As DropDownList = _ CType(e.Item.Cells(4).Controls(1), DropDownList) Dim SQL As String = _ "SELECT ShipperID, CompanyName FROM Shippers ORDER BY ShipperID" Dim DA As SqlDataAdapter = New SqlDataAdapter(SQL, ConnStr) Dim DS As New DataSet Dim item As ListItem DA.Fill(DS, "Shippers") DDL.DataSource = DS.Tables("Shippers").DefaultView DDL.DataTextField = "CompanyName" DDL.DataValueField = "ShipperID" DDL.DataBind() item = DDL.Items.FindByValue(CurrentShip) If Not item Is Nothing Then item.Selected = True End If End Sub
最后,編寫從 DropDownList 中檢索當前選定值的代碼,并執行數據庫更新:
Private Sub DataGrid1_UpdateCommand(ByVal source As Object, _ ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs) _ Handles DataGrid1.UpdateCommand Dim DDL As DropDownList = _ CType(e.Item.Cells(4).Controls(1), DropDownList) Dim NewShip As Integer = DDL.SelectedValue Dim OrderID As Integer = Int32.Parse(e.Item.Cells(1).Text) Dim SQL As String = _ "UPDATE Orders SET ShipVia=@Ship WHERE OrderID=@ID" Dim Conn As SqlConnection = New SqlConnection(ConnStr) Dim Cmd As New SqlCommand(SQL, Conn) Cmd.Parameters.Add(New SqlParameter("@Ship", NewShip)) Cmd.Parameters.Add(New SqlParameter("@ID", OrderID)) Conn.Open() Cmd.ExecuteNonQuery() Conn.Close() DataGrid1.EditItemIndex = -1 BindGrid() End Sub
所有列的基礎:DataGridColumn
我們回顧一下所有內置列類型的父類型 DataGridColumn 。(參見圖 1。)它包含所有 Datagrid 列中常用的屬性和方法。帶星號的類型表示您創建自定義列類型時要使用的類型。
DataGridColumn 屬性
- FooterStyle ( TableItemStyle )
- FooterText (字符串)
- HeaderImageUrl (字符串)
- HeaderStyle ( TableItemStyle )
- HeaderText (字符串)
- ItemStyle ( TableItemStyle )
- SortExpression (字符串)
- Visible (布爾值)
DataGridColumn 方法
- Initialize
- InitializeCell
- LoadViewState
- OnColumnChanged
- SaveViewState
- TrackViewState
可重復使用的方法:創建 DropDownColumn
首先要在 Microsoft? Visual Studio? .NET 中創建一個新類庫,并將其命名為 MyCustomColumn。添加一個新類 DropDownColumn ,并確保在您的類定義中添加命名空間,這樣您的初始代碼應如下所示:
Namespace MyCustomColumn Public Class DropDownColumn Inherits DataGridColumn Public DataSource As ICollection Public DataField As String Public DataTextField As String Public DataValueField As String End Class End Namespace
我還聲明了 4 個公共屬性,如下所示:
- DataSource 。它是用來填充 DropDownList 的數據集。可以是實現 ICollection 接口的任何內容。在本文的示例中,我使用 ArrayList 和 DataView 。
- DataField 。它是父 Datagrid 數據源中的字段,它與從下拉列表中選定的數據相對應。例如,如果 DataSource 包含一個狀態集, DataField 將類似于“StateCode”,也可以在表格中使用狀態隨意命名字段。
- DataTextField 。這是要顯示在下拉列表中的文本,可以是下面的值,也可以不是。
- DataValueField 。這是表示特殊下拉選項的值。 DataValueField 通常是一個整數值或其他代碼,而 DataTextField 是對用戶來說更有意義的文本說明。
接下來,覆蓋 InitializeCell ,它是 Datagrid 列的一個固有事件。列中的所有單元格都將發生 InitializeCell ,它與直接使用 Datagrid 時的 ItemCreated 事件非常相似。您可以使用它來管理單元格內容,例如設置 HeaderText ,添加您將向其中添加數據的 DropDownList 控件。我已經為單元格的 DataBinding 事件添加了處理程序,需要根據當前是否正在編輯行來采取不同的處理方式。每個 System.Web.UI.Control 都有一個 DataBinding 事件,當數據被綁定到控件時,您可以從這里訪問底層的數據,本例中為 Datagrid 中的 TableCell 對象。
Public Overrides Sub InitializeCell(ByVal cell As TableCell, _ ByVal columnIndex As Integer, _ ByVal itemType As ListItemType) MyBase.InitializeCell(cell, columnIndex, itemType) Select Case itemType Case ListItemType.Header cell.Text = HeaderText Case ListItemType.Item, ListItemType.AlternatingItem AddHandler cell.DataBinding, AddressOf ItemDataBinding Case ListItemType.EditItem AddHandler cell.DataBinding, AddressOf EditItemDataBinding Dim DDL As New DropDownList cell.Controls.Add(DDL) End Select End Sub
接下來是 ItemDataBinding 例程,當對 Datagrid 中的 Item 或 AlternatingItem 進行數據時,將觸發該例程。您需要引用回正在綁定的 TableCell ,可以直接轉換傳遞給事件的“發送者”對象,再使用 TableCell 的 NamingContainer 屬性引用當前的 DataGridItem 。這里只能以純文本格式顯示 DataField 的內容,就象顯示在 BoundColumn 中一樣。最后,如果用戶指定的字段不存在,我將為用戶顯示更友好的錯誤信息,而不是僅僅顯示“索引超出范圍”這樣的一般信息。
Private Sub ItemDataBinding(ByVal sender As Object, ByVal e As EventArgs) Dim cell As TableCell = CType(sender, TableCell) Dim DGI As DataGridItem = CType(cell.NamingContainer, DataGridItem) Try cell.Text = DGI.DataItem(DataField) Catch RangeEx As IndexOutOfRangeException Throw New Exception("Specified DataField was not found.") Catch OtherEx As Exception Throw New Exception(OtherEx.InnerException.ToString) End Try End Sub
下一步,編寫 EditItemDataBinding 事件的代碼,當某個行進入“編輯”模式時,將在我們的自定義列單元格上觸發該事件。再次引用當前單元格并在調用 InitializeCell 方法時插入 DropDownList 控件。在 DropDownList 中添加一個空項目作為第一個選項,如果列中的當前數據與您從 DataSource 集合中選擇并放在列表中的任何項目都不匹配,則選擇該選項。
然后,需要確定所傳入集合的類型。在本例中,我將處理兩種情況:通過 ArrayList 傳遞一組字符串,或者數據表中的 DataView ,它由 DataRowView 項目構成。對于字符串數據,我將輸入一個新的 ListItem ,并設置下拉項的值和文本。由于這兩種情況是相同的,所以這里只需要文本。但是我將選擇相應的項目來根據值作出選擇,以便與下一個示例保持一致,下一個示例將設置一個單獨的值屬性。對于 DataRowView 項目,上一個示例中已指出, DataRowViewInstance("FieldName") 返回一個表示該字段中的數據的對象。可以使用同樣的方法檢索 DataTextField 和 DataValueFields 需要的值。
最后,拋出一些異常以處理開發人員使用列時遇到的常見錯誤,例如向 DataField 屬性發送無效字段名,或傳入不兼容的 DataSource 類型。我已經對要彈出的異常消息進行了硬編碼,但希望您在實際的應用程序中將這些消息保存到更容易配置的位置。例如,如果您希望在全球范圍內使用您的應用程序,則可以保存到您的 web.config 文件或資源文件中。同樣,您不一定非要再次拋出“未找到指定的 DataField”異常,因為在 Datagrid 被置于“編輯”模式之前可能已經在 ItemDataBinding 事件中捕獲了該異常。
Private Sub EditItemDataBinding(ByVal sender As Object, _ ByVal e As EventArgs) Dim cell As TableCell = CType(sender, TableCell) Dim DDL As DropDownList = _ CType(cell.Controls(0), DropDownList) Dim DataSourceItem As Object Dim item As ListItem Dim DGI As DataGridItem '首先添加一個空選項 DDL.Items.Add(New ListItem("")) For Each DataSourceItem In DataSource Select Case DataSourceItem.GetType.ToString Case "System.String" '應用到 ArrayList 示例 item = New ListItem(DataSourceItem, DataSourceItem) DDL.Items.Add(item) Case "System.Data.DataRowView" Dim DRV As DataRowView = _ CType(DataSourceItem, DataRowView) item = New_ ListItem(DRV(DataTextField), DRV(DataValueField)) DDL.Items.Add(item) Case Else Throw New Exception("Invalid DataSource type.") End Select Next Try DGI = CType(cell.NamingContainer, DataGridItem) item = DDL.Items.FindByValue(DGI.DataItem(DataField)) Catch RangeEx As IndexOutOfRangeException Throw New Exception("Specified DataField was not found.") Catch OtherEx As Exception Throw New Exception(OtherEx.InnerException.ToString) End Try If Not item Is Nothing Then item.Selected = True End Sub
使用 DropDownColumn
以上是創建 DropDownColumn 類所需的所有代碼,下面我們看一看如何在應用程序中使用該控件。如果您是在家中學習,而且還沒有開始做,請將上面創建的命名空間編譯到 MyCustomColumn.dll 中,并將其復制到您想試驗的應用程序的 /bin 文件夾中。本例中,我創建一個新的 Web 應用程序 UseCustomColumn,并在我的 /bin 目錄的 MyCustomColumn.dll 中添加一個引用。在 ASPX 文件的頂部,添加 @Register 指令:
<%@ Register TagPrefix="dgg" Namespace="MyCustomColumn" Assembly="MyCustomColumn" %>
請注意,新的 Datagrid 列類型不會為 Datagrid 出現在 Visual Studio .NET 屬性生成器中,因此您需要進入 HTML 視圖并在其中添加列聲明。確保 Datagrid 聲明位于一組 <form runat="server">...</form> 標記之中,這些標記用于處理 PostBack。ASPX 文件的其余部分應如下所示:
<%@ Page Language="vb" AutoEventWireup="false" Codebehind="WebForm1.aspx.vb" Inherits="UseCustomColumn.WebForm1" Trace="False" Debug="True"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <HEAD> <title>WebForm1</title> <LINK rel="stylesheet" type="text/css" href="Styles.css"> <meta name="GENERATOR" content="Microsoft Visual Studio.NET 7.0"> <meta name="CODE_LANGUAGE" content="Visual Basic 7.0"> <meta name="vs_defaultClientScript" content="javascript"> <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5"> </HEAD> <body> <form id="Form1" method="post" runat="server"> <asp:DataGrid id="DataGrid1" runat="server" CssClass="grid" AutoGenerateColumns="False"> <Columns> <asp:EditCommandColumn EditText="Edit" CancelText="Cancel" UpdateText="Update" /> <asp:BoundColumn DataField="OrderID" ReadOnly="True" HeaderText="Order ID"/> <asp:BoundColumn DataField="ShipName" HeaderText="Ship to" ReadOnly="True"/> <asp:BoundColumn DataField="ShipCountry" HeaderText="Country" ReadOnly="True"/> <dgg:DropDownColumn DataField="ShipVia" HeaderText="Ship Method" /> </Columns> </asp:DataGrid> </form> </body> </HTML>
Datagrid 被綁定到 Northwind 示例的 Orders 表,自定義 DropDownColumn 被綁定到 ShipVia 列。現在我只設置 DataField 屬性,因為剛剛綁定到一個簡單的 ArrayList ,不需要 DataTextField 和 DataValueField 屬性。如果您有預定義的常數列表或者您需要一個快速設置選項的方法, ArrayList 選項最簡單。 DropDownColumn 的 DataSource 在代碼中設置,首先引用 DropDownColumn :
Dim DDC As MyCustomColumn.DropDownColumn DDC = CType(DataGrid1.Columns(4), MyCustomColumn.DropDownColumn) Dim AL As New ArrayList AL.Add("Shipping Company A") AL.Add("Shipping Company B") AL.Add("Shipping Company C") DDC.DataSource = AL
下面是運行此代碼的結果:
圖 3:使用 ArrayList
接下來,我需要轉換該示例以便使用數據庫中的活動表。 ShipVia 是查找表 Shippers 的外鍵,我在代碼中將其指定為 DropDownColumn 的 DataSource 。我還需要改變 DropDownColumn 聲明,以包括與 Shippers 表中的相應字段匹配的 DataTextField 和 DataValueField 名稱:
<dgg:DropDownColumn DataField="ShipVia" DataTextField="CompanyName" DataValueField="ShipperID" HeaderText="Ship Method" />
然后將兩個 Orders 表綁定到 Datagrid ,將 Shippers 表綁定到自定義列:
Dim SQL As String = "SELECT OrderID, ShipName, ShipCountry, ShipVia FROM Orders" Dim DA As SqlDataAdapter = New SqlDataAdapter(SQL, ConnStr) Dim DS As New DataSet DA.Fill(DS, "Orders") 'Dim Cmd As SqlCommand = New SqlCommand(SQL, Conn) 'Conn.Open() 'DataGrid1.DataSource = _ Cmd.ExecuteReader(CommandBehavior.CloseConnection) DataGrid1.DataSource = DS.Tables("Orders").DefaultView SQL = "SELECT ShipperID, CompanyName " & _ "FROM Shippers ORDER BY ShipperID" DA.SelectCommand.CommandText = SQL DA.Fill(DS, "Shippers") DDC.DataSource = DS.Tables("Shippers").DefaultView DataGrid1.DataBind()
DataGridColumn 使用活動數據,根據 Orders 表中的值(1、2 或 3)自動選擇正確的項目,如下所示:
圖 4:從數據庫中檢索數據
使用 DropDownColumn 的最后一步是檢索選定的值以傳遞回數據庫更新。為此,只需在單元格內引用 DropDownList 控件,并確定其 SelectedValue 屬性:
Private Sub DataGrid1_UpdateCommand( _ ByVal source As Object, _ ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs) _ Handles DataGrid1.UpdateCommand Dim CustomDDL As DropDownList = _ CType(e.Item.Cells(4).Controls(0), DropDownList) Dim NewShip As Integer = CustomDDL.SelectedValue Dim OrderID As Integer = Int32.Parse(e.Item.Cells(1).Text) Dim SQL As String = _ "UPDATE Orders SET ShipVia=@Ship WHERE OrderID=@ID" Dim Conn As SqlConnection = New SqlConnection(ConnStr) Dim Cmd As New SqlCommand(SQL, Conn) Cmd.Parameters.Add(New SqlParameter("@Ship", NewShip)) Cmd.Parameters.Add(New SqlParameter("@ID", OrderID)) Conn.Open() Cmd.ExecuteNonQuery() Conn.Close() DataGrid1.EditItemIndex = -1 BindGrid() End Sub
小結
上文概述了如何以 DataGridColumn 為父類型創建一個新類型、如何進行數據綁定以及如何將其應用到實際應用程序中。這只是可重復使用的 Datagrid 列的一個示例,因此,您需要檢查您自己的應用程序,以確定哪些重復的功能可以封裝到其自己的自定義 Datagrid 列中。您可以開發自己的列,以解決常見問題(例如,在列中顯示 DropDownList ),或滿足您公司的特殊需要。您也不必拘泥于本文的示例,只在自定義列中包含一個 ASP.NET 控件,您可以編寫更復雜的結構,例如將一系列控件、第三方內容或整個 Datagrid 控件嵌套到列中,以表現多層信息。總之,您可以充分發揮您的想象力。
5 個內置的列類型非常有用,它們可以滿足使用 Datagrid 控件進行顯示的大多數情況下的需要。現在并沒有開發您自己的控件,只是將一些有意義的內容隨便放到 TemplateColumn 中。創建自定義列使您可以突破這些限制,在您的 Datagrid 應用程序中添加豐富的功能。
作者簡介
“Datagrid 女孩”Marcie Robillard 是 Microsoft 最優秀的 ASP.NET 專家,她是一位獨立的 ASP.NET 顧問和培訓師。ASP.NET Datagrid 是她的專業,她還專門為此創建了一個 Web 站點 DatagridGirl.com 。您可以從該站點找到優秀 Datagrid 文章的鏈接、Datagrid 內容的書評以及不斷增加的 Datagrid 常見問題。Marcie 還花費了大量時間主持 ASP.NET 論壇,回答有關 Datagrid 的各種問題。Marcie 當前的任務是指導各公司開發自己的 .NET 技術。如果您的組織需要這方面的專業咨詢或培訓,請聯系 Marcie@DatagridGirl.com 。
參考站點:
MetaBuilders.com 。免費的自定義 Datagrid 列,包括源代碼 (C#)。
DatagridGirl.com 。有關 Datagrid 的各種資源。
Scott Mitchell 著的《ASP.NET Data Web Controls》,SAMS 2003 年出版。ISBN 0672325012
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
