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で連絡することができます。