Scott Mitchell による
このチュートリアルでは、GridView コントロールにチェック ボックスの列を追加して、GridView の複数の行を直感的に選択する方法をユーザーに提供する方法について説明します。
イントロダクション
前のチュートリアルでは、特定のレコードを選択するために GridView にラジオ ボタンの列を追加する方法を調べました。 ラジオ ボタンの列は、ユーザーがグリッドから最大 1 つの項目を選択するように制限されている場合に適したユーザー インターフェイスです。 ただし、ユーザーがグリッドから任意の数の項目を選択できるようにしたい場合もあります。 たとえば、Web ベースの電子メール クライアントでは、通常、メッセージの一覧がチェックボックスの列と共に表示されます。 ユーザーは任意の数のメッセージを選択し、メールを別のフォルダーに移動したり、削除したりするなどのアクションを実行できます。
このチュートリアルでは、チェックボックスの列を追加する方法と、ポストバックでチェックされたチェックボックスを決定する方法について説明します。 特に、Web ベースの電子メール クライアントのユーザー インターフェイスを厳密に模倣する例を構築します。 この例では、 Products
データベース テーブルの製品を一覧表示するページングされた GridView を、各行にチェック ボックスを付けます (図 1 を参照)。 [選択した製品の削除] ボタンをクリックすると、選択した製品が削除されます。
図 1: 各製品行にチェックボックスが含まれています (フルサイズの画像を表示する場合はクリックします)
手順 1: 製品情報を一覧表示する Paged GridView の追加
チェック ボックスの列の追加について心配する前に、まず、ページングをサポートする GridView に製品を一覧表示することに焦点を当ててみましょう。 まず、CheckBoxField.aspx
フォルダーのEnhancedGridView
ページを開き、ツールボックスからデザイナーに GridView をドラッグし、そのID
をProducts
に設定します。 次に、GridView を ProductsDataSource
という名前の新しい ObjectDataSource にバインドすることを選択します。
ProductsBLL
クラスを使用するように ObjectDataSource を構成し、GetProducts()
メソッドを呼び出してデータを返します。 この GridView は読み取り専用であるため、UPDATE タブ、INSERT タブ、DELETE タブのドロップダウン リストを (None) に設定します。
図 2: 名前付きの新しい ObjectDataSource ProductsDataSource
を作成する (フルサイズの画像を表示する をクリックします)
図 3: GetProducts()
メソッドを使用してデータを取得するように ObjectDataSource を構成する (フルサイズの画像を表示する をクリックします)。
図 4: [UPDATE]、[INSERT]、[DELETE] タブの [Drop-Down リスト] を [なし] に設定する (フルサイズの画像を表示する 場合はクリックします)
データ ソースの構成ウィザードが完了すると、Visual Studio によって、製品関連のデータ フィールドに対して BoundColumns と CheckBoxColumn が自動的に作成されます。 前のチュートリアルで行ったように、BoundFields ProductName
、 CategoryName
、 UnitPrice
以外のすべてを削除し、 HeaderText
プロパティを Product、Category、Price に変更します。 値が通貨として書式設定されるように、 UnitPrice
BoundField を構成します。 また、スマート タグの [ページングを有効にする] チェック ボックスをオンにして、ページングをサポートするように GridView を構成します。
選択した製品を削除するためのユーザー インターフェイスも追加しましょう。 GridView の下に Button Web コントロールを追加し、その ID
を DeleteSelectedProducts
に設定し、その Text
プロパティを [選択した製品の削除] に設定します。 この例では、データベースから製品を実際に削除するのではなく、削除された製品を示すメッセージを表示します。 これに対応するには、ボタンの下にラベル Web コントロールを追加します。 ID を DeleteResults
に設定し、 Text
プロパティをクリアし、 Visible
プロパティと EnableViewState
プロパティを False
に設定します。
これらの変更を行った後、GridView、ObjectDataSource、Button、および Label の宣言型マークアップは次のようになります。
<p>
<asp:GridView ID="Products" runat="server" AutoGenerateColumns="False"
DataKeyNames="ProductID" DataSourceID="ProductsDataSource"
AllowPaging="True" EnableViewState="False">
<Columns>
<asp:BoundField DataField="ProductName" HeaderText="Product"
SortExpression="ProductName" />
<asp:BoundField DataField="CategoryName" HeaderText="Category"
ReadOnly="True" SortExpression="CategoryName" />
<asp:BoundField DataField="UnitPrice" DataFormatString="{0:c}"
HeaderText="Price" HtmlEncode="False"
SortExpression="UnitPrice" />
</Columns>
</asp:GridView>
<asp:ObjectDataSource ID="ProductsDataSource" runat="server"
OldValuesParameterFormatString="original_{0}"
SelectMethod="GetProducts" TypeName="ProductsBLL">
</asp:ObjectDataSource>
</p>
<p>
<asp:Button ID="DeleteSelectedProducts" runat="server"
Text="Delete Selected Products" />
</p>
<p>
<asp:Label ID="DeleteResults" runat="server" EnableViewState="False"
Visible="False"></asp:Label>
</p>
ブラウザーでページを表示します (図 5 を参照)。 この時点で、最初の 10 個の製品の名前、カテゴリ、価格が表示されます。
図 5: 最初の 10 製品の名前、カテゴリ、および価格が一覧表示されます (フルサイズの画像を表示する をクリックします)。
手順 2: チェック ボックスの列を追加する
ASP.NET 2.0 には CheckBoxField が含まれるため、GridView にチェックボックスの列を追加するために使用できると考えられる場合があります。 残念ながら、これはそうではありません。CheckBoxField はブール型のデータ フィールドを操作するように設計されているためです。 つまり、CheckBoxField を使用するには、レンダリングされたチェック ボックスがオンになっているかどうかを判断するために値を参照する基になるデータ フィールドを指定する必要があります。 CheckBoxField を使用して、チェック ボックスをオフにした列だけを含めることはできません。
代わりに、TemplateField を追加し、CheckBox Web コントロールをその ItemTemplate
に追加する必要があります。 先に進み、 Products
GridView に TemplateField を追加し、最初の (左端) フィールドにします。 GridView のスマート タグで、[テンプレートの編集] リンクをクリックし、ツールボックスから CheckBox Web コントロールを ItemTemplate
にドラッグします。 この CheckBox の ID
プロパティを ProductSelector
に設定します。
図 6: ProductSelector
という名前の CheckBox Web コントロールを TemplateField の ItemTemplate
に追加する (フルサイズの画像を表示する をクリックします)
TemplateField と CheckBox Web コントロールが追加された状態で、各行にチェック ボックスが含まれるようになりました。 図 7 は、TemplateField と CheckBox が追加された後、ブラウザーで表示された場合のこのページを示しています。
図 7: 各製品行にチェックボックスが含まれるようになりました (フルサイズの画像を表示する場合はクリックします)
手順 3: ポストバックでチェックされたチェック ボックスを決定する
この時点で、チェック ボックスの列がありますが、ポストバックでチェックされたチェック ボックスを決定する方法はありません。 ただし、[選択した製品の削除] ボタンをクリックすると、それらの製品を削除するためにチェック ボックスがオンになっている必要があります。
GridView の Rows
プロパティ を使用すると、GridView 内のデータ行にアクセスできます。 これらの行を反復処理し、プログラムによって CheckBox コントロールにアクセスし、その Checked
プロパティを調べて、CheckBox が選択されているかどうかを確認できます。
DeleteSelectedProducts
Button Web コントロールのClick
イベント ハンドラーを作成し、次のコードを追加します。
Protected Sub DeleteSelectedProducts_Click(sender As Object, e As EventArgs) _
Handles DeleteSelectedProducts.Click
Dim atLeastOneRowDeleted As Boolean = False
' Iterate through the Products.Rows property
For Each row As GridViewRow In Products.Rows
' Access the CheckBox
Dim cb As CheckBox = row.FindControl("ProductSelector")
If cb IsNot Nothing AndAlso cb.Checked Then
' Delete row! (Well, not really...)
atLeastOneRowDeleted = True
' First, get the ProductID for the selected row
Dim productID As Integer = _
Convert.ToInt32(Products.DataKeys(row.RowIndex).Value)
' "Delete" the row
DeleteResults.Text &= String.Format( _
"This would have deleted ProductID {0}<br />", productID)
'... To actually delete the product, use ...
' Dim productAPI As New ProductsBLL
' productAPI.DeleteProduct(productID)
'............................................
End If
Next
' Show the Label if at least one row was deleted...
DeleteResults.Visible = atLeastOneRowDeleted
End Sub
Rows
プロパティは、GridView のデータ行を構成するGridViewRow
インスタンスのコレクションを返します。 ここで For Each
ループは、このコレクションを列挙します。
GridViewRow
オブジェクトごとに、行の CheckBox にはrow.FindControl("controlID")
を使用してプログラムでアクセスします。 CheckBox をオンにすると、対応する行の ProductID
値が DataKeys
コレクションから取得されます。 この演習では、 DeleteResults
Label に有益なメッセージを表示するだけですが、実際のアプリケーションでは、代わりに ProductsBLL
クラスの DeleteProduct(productID)
メソッドを呼び出します。
このイベント ハンドラーを追加すると、[選択した製品の削除] ボタンをクリックすると、選択した製品の ProductID
が表示されるようになりました。
図 8: [選択した製品の削除] ボタンがクリックされると、選択した製品 ProductID
が表示されます (フルサイズの画像を表示する をクリックします)。
手順 4: [すべてチェック] ボタンと [すべてのチェック ボックスのオフ] ボタンを追加する
ユーザーが現在のページのすべての製品を削除する場合は、10 個の各チェック ボックスをオンにする必要があります。 このプロセスを迅速化するには、[すべてチェック] ボタンを追加します。このボタンをクリックすると、グリッド内のすべてのチェック ボックスがオンになります。 [すべてオフ] ボタンも同様に役立ちます。
2 つのボタン Web コントロールをページに追加し、GridView の上に配置します。 最初の 1 ID
を CheckAll
に設定し、その Text
プロパティを Check All に設定します。2 つ目の ID
を UncheckAll
に設定し、 Text
プロパティを [すべてオフ] に設定します。
<asp:Button ID="CheckAll" runat="server" Text="Check All" />
<asp:Button ID="UncheckAll" runat="server" Text="Uncheck All" />
次に、 ToggleCheckState(checkState)
という名前の分離コード クラスにメソッドを作成します。このメソッドを呼び出すと、 Products
GridView Rows
コレクションが列挙され、各 CheckBox Checked
プロパティに渡された checkState パラメーターの値が設定されます。
Private Sub ToggleCheckState(ByVal checkState As Boolean)
' Iterate through the Products.Rows property
For Each row As GridViewRow In Products.Rows
' Access the CheckBox
Dim cb As CheckBox = row.FindControl("ProductSelector")
If cb IsNot Nothing Then
cb.Checked = checkState
End If
Next
End Sub
次に、Click
ボタンとCheckAll
ボタンのUncheckAll
イベント ハンドラーを作成します。
CheckAll
のイベント ハンドラーで、単に ToggleCheckState(True)
; を呼び出します。UncheckAll
では、ToggleCheckState(False)
を呼び出します。
Protected Sub CheckAll_Click(sender As Object, e As EventArgs) _
Handles CheckAll.Click
ToggleCheckState(True)
End Sub
Protected Sub UncheckAll_Click(sender As Object, e As EventArgs) _
Handles UncheckAll.Click
ToggleCheckState(False)
End Sub
このコードでは、[すべてチェック] ボタンをクリックするとポストバックが発生し、GridView のすべてのチェック ボックスがオンになります。 同様に、[すべてオフ] をクリックすると、すべてのチェック ボックスがオフになります。 図 9 は、[すべてチェック] ボタンがオンになった後の画面を示しています。
図 9: [すべてチェック] ボタンをクリックすると、すべてのチェック ボックスがオンになります (フルサイズの画像を表示する場合にクリックします)
注
チェックボックスの列を表示する場合、すべてのチェックボックスを選択または選択解除する方法の1つは、ヘッダー行のチェックボックスを使用することです。 さらに、現在の Check All/Uncheck All 実装にはポストバックが必要です。 ただし、チェックボックスは完全にクライアント側スクリプトを使用してオンまたはオフにすることができます。これにより、より迅速なユーザー エクスペリエンスが提供されます。 クライアント側の手法を使用した検討と合わせて、ヘッダー行のチェックボックスを使って「すべて選択」および「すべて解除」を実装する方法を詳しく調べるには、「Client-Side スクリプトを使用して GridView のすべてのチェックボックスを操作する方法」を参照してください。
概要
続行する前にユーザーが GridView から任意の数の行を選択できるようにする必要がある場合は、チェックボックスの列を追加することが 1 つのオプションです。 このチュートリアルで説明したように、GridView にチェック ボックスの列を含めると、CheckBox Web コントロールを使用して TemplateField を追加する必要があります。 Web コントロールを使用して (前のチュートリアルで行ったように、テンプレートにマークアップを直接挿入するのではなく)、ASP.NET は CheckBox の内容を自動的に記憶し、ポストバック全体でチェックされませんでした。 また、プログラムによってコード内の CheckBox にアクセスして、特定の CheckBox がチェックされているかどうかを判断したり、チェックされた状態を変更したりすることもできます。
このチュートリアルと最後のチュートリアルでは、GridView に行セレクター列を追加する方法について説明しました。 次のチュートリアルでは、少しの作業で GridView に挿入機能を追加する方法について説明します。
プログラミングに満足!
著者について
7 冊の ASP/ASP.NET 書籍の著者であり、4GuysFromRolla.com の創設者である Scott Mitchell は、1998 年から Microsoft Web テクノロジを使用しています。 Scott は、独立したコンサルタント、トレーナー、ライターとして働いています。 彼の最新の本は サムズ・ティーチ・セルフ ASP.NET 24時間で2.0です。 彼にはmitchell@4GuysFromRolla.comで連絡することができます。