チュートリアル : GridView Web サーバー コントロールにバインドされた行の一括更新を実行する
更新 : 2007 年 11 月
GridView コントロールの編集が有効になっている場合は、既定により、行を 1 行ずつ編集できます。このチュートリアルでは、1 回のクリックで複数の行の変更をまとめて保存できるように、GridView コントロールの機能を拡張する方法について説明します。このチュートリアルでは、SqlDataSource コントロールを使用して、データ ソースから結果を取得し、更新を管理します。SqlDataSource コントロールは、GridView コントロールのデータ ソースとして機能します。
このチュートリアルでは、次の作業を行う方法について説明します。
Microsoft Visual Web Developer から SQL Server データベースに接続します。
SqlDataSource コントロールを使用して、データ アクセスの管理を行います。
GridView コントロールで、データベースから返されたデータを表示します。
複数の行をまとめて編集できるように GridView コントロールを構成します。
必要条件
このチュートリアルを実行するために必要な項目や条件は、次のとおりです。
Visual Web Developer (Visual Studio)。
MDAC (Microsoft Data Access Components ) Version 2.7 以降。
Microsoft Windows XP または Windows Server 2003 を使用している場合、MDAC 2.7 は既に存在します。ただし、Microsoft Windows 2000 を使用している場合は、コンピュータに既にインストールされている MDAC のアップグレードが必要になる場合があります。詳細については、MSDN ライブラリの記事「Microsoft Data Access Components (MDAC) Installation」を参照してください。
SQL Server Northwind データベースへのアクセス。SQL Server の Northwind データベースのコピーを入手する方法については、SQL Server 2005 Books Online の記事「サンプル データベースのインストール」を参照してください。
メモ : SQL Server が実行されているコンピュータにログオンする方法については、サーバー管理者にお問い合わせください。
Web サイトの作成
「チュートリアル : Visual Web Developer での基本的な Web ページの作成」を完了して、Visual Web Developer で Web サイトを既に作成している場合は、その Web サイトを使用して、次のセクションに移動できます。それ以外の場合は、次の手順に従って、新しい Web サイトおよびページを作成します。
ファイル システム Web サイトを作成するには
Visual Web Developer を開きます。
[ファイル] メニューの [新規作成] をポイントし、[Web サイト] をクリックします。Visual Web Developer Express を使用している場合は、[ファイル] メニューの [新しい Web サイト] をクリックします。
[新しい Web サイト] ダイアログ ボックスが表示されます。
[Visual Studio にインストールされたテンプレート] の [ASP.NET Web サイト] をクリックします。
[場所] ボックスの一覧で、[ファイル システム] をクリックし、Web サイトのページを格納するフォルダの名前を入力します。
たとえば、フォルダ名として「C:\WebSites\BulkUpdate」と入力します。
[言語] ボックスの一覧で、作業に使用するプログラミング言語をクリックします。
[OK] をクリックします。
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 SQL Server 用データ プロバイダ] をクリックし、[続行] をクリックします。
[接続の追加] ページの [サーバー名] ボックスに、SQL Server Northwind データベースを実行しているコンピュータの名前を入力します。
[サーバーにログオンする] で、SQL Server データベースのアクセスに使用する適切なオプション (統合セキュリティまたは特定の ID およびパスワード) を選択します。必要な場合は、ユーザー名とパスワードを入力します。
メモ : SQL Server が実行されているコンピュータにログオンする方法については、サーバー管理者にお問い合わせください。
パスワードを入力した場合は、[パスワードの保存] チェック ボックスをオンにします。
[データベースの選択または入力] をクリックし、「Northwind」と入力します。
[接続の確認] をクリックして、接続を確認したら [OK] をクリックします。
データ ソースの構成ウィザードの [次へ] をクリックします。
[はい、この接続を次の名前で保存します] チェック ボックスがオンになっていることを確認します。
「NorthwindConnectionString」という接続名を指定し、[次へ] をクリックします。
[Select ステートメント構成] ページの [テーブルまたは表示から列を指定します] をクリックします。
[名前] ボックスの一覧の [Employees] をクリックします。
[列] の下の [EmployeeID]、[LastName]、および [FirstName] を選択します。
[詳細] をクリックします。
[INSERT、UPDATE、および DELETE ステートメントの生成] チェック ボックスをオンにし、[OK] をクリックします。
[次へ] をクリックします。
[完了] をクリックします。
データを表示する GridView コントロールの追加
データ管理を行うようにデータ ソース コントロールを構成できたら、ページ上のコントロールにデータを表示します。
次の手順では、GridView コントロールにデータを表示します。GridView コントロールは、以前に追加した SqlDataSource コントロールからデータを取得します。
GridView コントロールのコンテンツを 1 行ずつ編集するのではなく、一括編集できるようにするには、GridView コントロールをカスタマイズする必要があります。各列の既定の表示要素を編集可能な要素で置き換え、それらをデータ ソースにバインドします。このためには、TemplateField 列を作成します。各 TemplateField 列の ItemTemplate で、ユーザーがデータの編集に使用する、バインドされた TextBox コントロールを追加します。
データを表示するために GridView コントロールを追加および設定するには
Default.aspx ページのデザイン ビューで作業中であることを確認します。
ツールボックスの [データ] タブをクリックし、GridView コントロールをページにドラッグします。
[GridView タスク] パネルの [データ ソースの選択] ボックスの一覧で、以前に追加した SqlDataSource コントロールである [SqlDataSource1] をクリックします。
[ページングを有効にする] を選択します。
[列の編集] をクリックします。
[フィールド] ダイアログ ボックスが表示されます。
[選択されたフィールド] で [FirstName] を選択します。
[このフィールドを TemplateField に変換します] をクリックします。
[FirstName] フィールドと同じ手順で、[LastName] フィールドをテンプレート フィールドに変換します。[EmployeeId] フィールドを変換しないでください。このフィールドには主キーが含まれているため、編集できません。
[OK] をクリックします。
[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] フィールドに収まらないほど多くの情報を入力する状況を防ぐことができます。
前の 9 つの手順を 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 Sub
protected 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 Sub
private 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 コントロールがデータ バインディングを実行するたびに実行されます。最初の行のバインディング中に、元のデータベース値のコピーが 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 Sub
protected 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 Function
protected 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 コントロールのテキストに書式を設定している場合、値は等しくても文字列表現は一致しません。たとえば、DateTime の値に短い日付表記 ({0:d}) の書式を適用した場合、日付の 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 コントロールで値を編集できるように設定することもできます。詳細については、次のトピックを参照してください。
参照
処理手順
方法 : データ ソース コントロールを使用するときに接続文字列をセキュリティ保護する