更新:2007 年 11 月
在已啟用 GridView 控制項的編輯功能時,依預設一次只能編輯一個資料列。本逐步解說會說明如何擴充 GridView 控制項的功能,讓使用者可以修改多個資料列,並藉由按一下按鈕來儲存所有的變更。本逐步解說使用 SqlDataSource 控制項從資料來源擷取結果並管理更新。SqlDataSource 控制項可當做 GridView 控制項的資料來源。
在瀏覽這份逐步解說期間,您將了解如何:
連接到 Microsoft Visual Web Developer 中的 SQL Server 資料庫。
使用 SqlDataSource 控制項管理資料存取。
顯示從 GridView 控制項中的資料庫傳回的資料。
將 GridView 控制項設定為讓使用者可以一次編輯多個資料列。
必要條件
若要完成這個逐步解說,您必須要有:
Visual Web Developer (Visual Studio)。
Microsoft Data Access Components (MDAC) 2.7 (含) 以後版本。
如果您使用的是 Microsoft Windows XP 或 Windows Server 2003,就表示已經有 MDAC 2.7。不過,如果您使用的是 Microsoft Windows 2000,就可能需要升級電腦中所安裝的 MDAC。如需詳細資訊,請參閱 MSDN Library 中的文件 Microsoft Data Access Components (MDAC) 安裝。
存取 SQL Server Northwind 資料庫。如果需要 SQL Server 的 Northwind 資料庫副本,請參閱《SQL Server 2005 線上叢書》中的安裝範例資料庫。
注意事項:如果您需要如何登入執行 SQL Server 之電腦的相關資訊,請聯繫伺服器管理員。
建立網站
如果您已經藉由完成逐步解說:在 Visual Web Developer 中建立基本 Web 網頁中的步驟而在 Visual Web Developer 中建立了網站,則可以使用該網站,並繼續進行下一節的步驟。否則,請依照下列這些步驟建立新的網站和 Web 網頁。
若要建立檔案系統網站
開啟 Visual Web Developer。
在 [檔案] 功能表上按一下 [新增],然後按一下 [網站]。如果您是使用 Visual Web Developer Express,請在 [檔案] 功能表中按一下 [新網站]。
[新網站] 對話方塊隨即出現。
請在 [Visual Studio 安裝的範本] 下方,按一下 [ASP.NET 網站]。
在 [位置] 清單中,按一下 [檔案系統],然後輸入您想要用來保存網站頁面的資料夾名稱。
例如,輸入資料夾名稱 C:\WebSites\BulkUpdate。
在 [語言] 清單中,請按一下您想要操作的程式語言。
按一下 [確定]。
Visual Web Developer 會建立資料夾和命名為 Default.aspx 的新頁面。
加入 GridView 控制項的資料來源
若要在 ASP.NET Web 網頁上顯示資料,您需要下列項目:
資料來源 (例如資料庫) 的連接。
在下列程序中,您將建立 SQL Server Northwind 資料庫的連接。
頁面上的資料來源控制項,會與資料來源 (資料庫) 互動以讀取和寫入資料。
頁面上的控制項,用以顯示資料。
在下列程序中,您將會在 GridView 控制項中顯示資料。GridView 控制項將會從 SqlDataSource 控制項取得其資料。
若要加入 GridView 控制項的資料來源
開啟或切換至 Default.aspx 頁面
切換至 [設計] 檢視。
從 [工具箱] 的 [資料] 索引標籤中,將 SqlDataSource 控制項拖曳到頁面上。
如果 [SqlDataSource 工作] 智慧標籤沒有出現,請以滑鼠右鍵按一下 SqlDataSource 控制項,再按一下 [顯示智慧標籤]。
在 [SqlDataSource 工作] 面板中,按一下 [設定資料來源]。
[設定資料來源] 精靈便會出現。
按一下 [新增連接]。
[加入連接] 對話方塊隨即出現。
如有必要,請進行下列步驟之一:您看到的實際 UI 會依據先前在 Visual Web Developer 中所進行的資料連接而定。
如果 [資料來源] 清單未顯示 [Microsoft SQL Server (SqlClient)],請按一下 [變更],然後在 [變更資料來源] 對話方塊中選取 [Microsoft SQL Server]。
如果出現 [選擇資料來源] 對話方塊而不是 [連接屬性] 對話方塊,請在 [資料來源] 清單中選取要使用的資料來源類型。在此逐步解說中,資料來源型別為 Microsoft SQL Server。在 [資料提供者] 清單中,按一下 [.NET Framework Data Provider for SQL Server],然後按一下 [繼續]。
在 [加入連接] 頁面的 [伺服器名稱] 文字方塊中,輸入執行 SQL Server Northwind 資料庫的電腦名稱。
在 [登入伺服器] 下,選取正確的選項以存取 SQL Server 資料庫 (整合式安全性或特定的 ID 和密碼)。視需要輸入使用者名稱和密碼。
注意事項:如果您需要如何登入執行 SQL Server 之電腦的相關資訊,請聯繫伺服器管理員。
如果您輸入密碼,請選取 [儲存我的密碼] 核取方塊。
按一下 [選取或輸入資料庫名稱],然後輸入 Northwind。
按一下 [測試連接],只要您確定連接已正常運作後,按一下 [確定]。
在 [設定資料來源] 精靈中按一下 [下一步]。
確定已選取 [是,將這個連接儲存為] 核取方塊。
將連接命名為 [NorthwindConnectionString],然後按一下 [下一步]。
在 [設定 Select 陳述式] 頁面中,選取 [指定資料表或檢視的資料行]。
從 [名稱] 清單中,選取 [Employees]。
選取 [資料行] 底下的 [EmployeeID]、[LastName] 和 [FirstName]。
按一下 [進階]。
選取 [產生 INSERT、UPDATE、和 DELETE 陳述式] 核取方塊,然後按一下 [確定]。
按一下 [下一步]。
按一下 [完成]。
加入 GridView 控制項以顯示資料
在設定資料來源控制項來管理資料之後,頁面上還需要控制項來顯示資料。
在下列程序中,您將會在 GridView 控制項中顯示資料。GridView 控制項將會從之前所加入的 SqlDataSource 控制項取得其資料。
若要讓使用者一次編輯所有 GridView 控制項的內容 (而不是一次只編輯一個資料列),則必須自訂 GridView 控制項。您要使用可編輯的項目來取代每個資料行中的預設顯示項目,然後將其繫結到資料來源。若要完成這項作業,需要建立 TemplateField 資料行。在每個 TemplateField 資料行的 ItemTemplate 中,需要加入使用者可在其中編輯資料的繫結 TextBox 控制項。
若要加入並設定用於顯示資料的 GridView 控制項
確定您在 Default.aspx 頁面的 [設計] 檢視中。
從 [工具箱] 的 [資料] 索引標籤,將 [GridView] 控制項拖曳到頁面上。
在 [GridView 工作] 面板的 [選擇資料來源] 清單方塊中,選取先前加入的 SqlDataSource 控制項 SqlDataSource1。
選取 [啟用分頁]。
按一下 [編輯資料行]。
[欄位] 對話方塊隨即出現。
選取 [選取的欄位] 底下的 [FirstName]。
按一下 [將這個欄位轉換為 TemplateField]。
使用針對 FirstName 欄位所用的同樣步驟,將 LastName 欄位轉換為範本欄位。請勿轉換 EmployeeId 欄位,因為它包含主索引鍵,因此不可編輯。
按一下 [確定]。
在 [GridView 工作] 面板中,按一下 [編輯樣板]。
在 [顯示] 清單中,按一下 [FirstName] 底下的 [EditItemTemplate]。
GridView 控制項所顯示的可編輯區域,具有編輯模式之 [FirstName] 資料行的預設配置。
在 EditItemTemplate 中以滑鼠右鍵按一下 TextBox 控制項,然後按一下 [複製]。
以滑鼠右鍵按一下 GridView 控制項,再按一下 [顯示智慧標籤]。
在 [顯示] 清單中,按一下 [FirstName] 底下的 [ItemTemplate]。
GridView 控制項現在會以顯示模式來顯示 [FirstName] 資料行的預設配置。
刪除現有的 Label 控制項。
以滑鼠右鍵按一下 [ItemTemplate] 可編輯區域,然後按一下 [貼上]。
您已經將 TextBox 控制項 (包括其資料繫結組態) 從 EditItemTemplate 配置複製到 ItemTemplate 配置。
選取 TextBox 控制項,在 [屬性] 視窗中將 [(ID)] 屬性設定為 FirstNameTextBox。這樣可以確保您所貼上的 TextBox 控制項與您所複製的控制項有不同的 ID。
將 [MaxLength] 屬性設定為 10 (資料庫中的欄位長度上限)。
這樣可確保使用者所輸入的資訊,不會超過資料庫中 [FirstName] 欄位所設定的儲存上限。
重複前面的九個步驟,但這次修改 [LastName] 範本欄位。將現有的 Label 控制項取代為從 [EditItemTemplate] 配置所複製的 TextBox,並將 ID 屬性設定為 LastNameTextBox。
將 TextBox 控制項之 MaxLength 屬性的值指定為 20。
以滑鼠右鍵按一下 [GridView] 控制項,然後按一下 [結束範本編輯]。
加入執行大量更新的程序
將 GridView 控制項設定為顯示可編輯資料之後,就需要加入執行大量更新的程式碼。在本章節中,您將執行下列作業:
加入 Button 控制項,並且在其 Click 處理常式中加入程式碼,以大量更新 GridView 控制項的每個資料列變更。
加入儲存原始資料值的 DataTable 物件。
加入程式碼以判斷資料列是否經過修改。目前顯示在 GridView 控制項中的值將會與儲存在 DataTable 物件中的原始值進行比較。如果有一個或多個顯示的值與原始值不符,就會更新資料庫中的資料列;否則,在大量更新時並不會包含該資料列。
若要建立執行大量更新的程序
切換至 [設計] 檢視。
選取 GridView 控制項,並在 [屬性] 視窗中,按一下 [事件] 按鈕 (
) 以顯示 GridView 控制項的事件。在 RowDataBound 欄位中輸入 GridView1_RowDataBound,然後按 ENTER 鍵。
Visual Web Developer 會為 GridView 控制項的 RowDataBound 事件建立事件處理常式。此程式碼將看起來與下列範例相同。
Protected Sub GridView1_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles GridView1.RowDataBound End Subprotected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e) { }使用下列程式碼 (包括私用變數) 取代產生的程序。
Private tableCopied As Boolean = False Private originalDataTable As System.Data.DataTable Protected Sub GridView1_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles GridView1.RowDataBound If e.Row.RowType = DataControlRowType.DataRow Then If Not tableCopied Then originalDataTable = CType(e.Row.DataItem, System.Data.DataRowView).Row.Table.Copy() ViewState("originalValuesDataTable") = originalDataTable tableCopied = True End If End If End Subprivate bool tableCopied = false; private DataTable originalDataTable; protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e) { if (e.Row.RowType == DataControlRowType.DataRow) if (!tableCopied) { originalDataTable = ((DataRowView)e.Row.DataItem).Row.Table.Copy(); ViewState["originalValuesDataTable"] = originalDataTable; tableCopied = true; } }此程式碼會在每次 GridView 控制項執行資料繫結 (Data Binding) 時執行。在進行第一個資料列的繫結時,程式碼會將原始資料庫值的副本儲存在 DataTable 物件中,該物件則會儲存在 ViewState 中。
切換至 [設計] 檢視。
從 [工具箱] 的 [標準] 索引標籤,將 [Button] 控制項拖曳到頁面上。
在 [屬性] 視窗中按一下 [屬性] 按鈕 (
),以顯示 Button 控制項的屬性。在 [(ID)] 欄位中輸入 UpdateButton。
在 [Text] 欄位中輸入 Update。
按一下 [事件] 按鈕 (
),以顯示 Button 控制項的事件。在 [Click] 欄位中輸入 UpdateButton_Click,並按 ENTER 鍵。
Visual Web Developer 會針對 Button 控制項的 Click 事件建立事件處理常式。此程式碼將看起來與下列範例相同。
Protected Sub UpdateButton_Click(ByVal sender As Object, ByVal e As EventArgs) End Subprotected void UpdateButton_Click(object sender, EventArgs e) { }以下列程式碼取代產生的程序:
Protected Sub UpdateButton_Click(ByVal sender As Object, ByVal e As EventArgs) originalDataTable = CType(ViewState("originalValuesDataTable"), System.Data.DataTable) For Each r As GridViewRow In GridView1.Rows If IsRowModified(r) Then GridView1.UpdateRow(r.RowIndex, False) Next ' Rebind the Grid to repopulate the original values table. tableCopied = False GridView1.DataBind() End Sub Protected Function IsRowModified(ByVal r As GridViewRow) As Boolean Dim currentID As Integer Dim currentLastName As String Dim currentFirstName As String currentID = Convert.ToInt32(GridView1.DataKeys(r.RowIndex).Value) currentLastName = CType(r.FindControl("LastNameTextBox"), TextBox).Text currentFirstName = CType(r.FindControl("FirstNameTextBox"), TextBox).Text Dim row As System.Data.DataRow = _ originalDataTable.Select(String.Format("EmployeeID = {0}", currentID))(0) If Not currentLastName.Equals(row("LastName").ToString()) Then Return True If Not currentFirstName.Equals(row("FirstName").ToString()) Then Return True Return False End Functionprotected void UpdateButton_Click(object sender, EventArgs e) { originalDataTable = (DataTable)ViewState["originalValuesDataTable"]; foreach (GridViewRow r in GridView1.Rows) if (IsRowModified(r)) { GridView1.UpdateRow(r.RowIndex, false); } // Rebind the Grid to repopulate the original values table. tableCopied = false; GridView1.DataBind(); } protected bool IsRowModified(GridViewRow r) { int currentID; string currentLastName; string currentFirstName; currentID = Convert.ToInt32(GridView1.DataKeys[r.RowIndex].Value); currentLastName = ((TextBox)r.FindControl("LastNameTextBox")).Text; currentFirstName = ((TextBox)r.FindControl("FirstNameTextBox")).Text; DataRow row = originalDataTable.Select(String.Format("EmployeeID = {0}", currentID))[0]; if (!currentLastName.Equals(row["LastName"].ToString())) { return true; } if (!currentFirstName.Equals(row["FirstName"].ToString())) { return true; } return false; }
注意事項:此程序會使用每個可編輯 TextBox 控制項中的值以及儲存在快取的 DataTable 物件中的值,執行字串比較作業。如果已經設定 TextBox 控制項文字的格式,則這些值可能相同,但其字串表示並不相符。例如,如果已經使用小型日期格式 ({0:d}) 設定了 DateTime 值的格式,則日期 TextBox 控制項中的值可能是 3/2/2005。DataTable 物件日期值的字串表示將是 3/2/2005 12:00 AM。在這些情況下,您所加入的比較邏輯必須考量格式及當地語系化等設定。
此程序會在 GridView 控制項的資料列中逐一查看,並針對每個資料列呼叫自訂的 IsRowModified 函式。此函式會將目前的資料列與 DataTable 物件中相對應的資料列相比較,如果該資料列已經變更,就會傳回 true。如果是已經變更的資料列,則按鈕 Click 處理常式中的程式碼就會呼叫 GridView 控制項的 UpdateRow 方法。
測試網頁
您現在可以執行網頁來測試程式碼。
若要測試網頁
按 CTRL+F5 執行頁面。
頁面會出現在瀏覽器中。GridView 控制項會在資料的可編輯頁面中,顯示 Northwind Employees 資料表的資料列。
修改一些值。
按一下 [更新]。
修改過的資料列會在資料庫中更新。
關閉瀏覽器。
後續步驟
本逐步解說已說明如何擴充 GridView 控制項的功能,以在 ASP.NET Web 網頁上更新多個資料列。您可能還想擴充應用程式,讓使用者可以使用 DetailsView 或 FormView 控制項加入新的資料列。您也可以讓使用者使用 TextBox 控制項以外的控制項來編輯值,例如 DropDownList 控制項。如需詳細資訊,請參閱下列主題: