Share via


チェックボックスの GridView 列を追加する (VB)

作成者: Scott Mitchell

PDF のダウンロード

このチュートリアルでは、GridView コントロールにチェック ボックスの列を追加して、複数行の GridView のより使いやすい選択方法をユーザーに提供する方法について説明します。

はじめに

前のチュートリアルでは、特定のレコードを選択ぶために GridView にラジオ ボタンの列を追加する方法を調べました。 ラジオ ボタンの列は、ユーザーがグリッドで選ぶ項目が多くても 1 つに制限されている場合に適したユーザー インターフェイスです。 ただし、ユーザーがグリッドから任意の数の項目を選択できるようにしたい場合もあります。 たとえば、Web ベースのメール クライアントでは、通常、メッセージの一覧がチェック ボックスの列と共に表示されます。 ユーザーは任意の数のメッセージを選んでから、メールの別のフォルダーへの移動や削除などのアクションを実行できます。

このチュートリアルでは、チェック ボックスの列を追加する方法と、ポストバックでオンにされたチェック ボックスを判別する方法について説明します。 具体的には、Web ベースのメール クライアントのユーザー インターフェイスによく似た例を作成します。 この例には、Products データベース テーブル内の製品の一覧を、各行にチェック ボックスを付けて表示する、ページングされた GridView が含まれます (図 1 を参照)。 [Delete Selected Products] ボタンがクリックされたら、選ばれている製品を削除します。

Each Product Row Includes a Checkbox

図 1: 製品の行ごとにチェック ボックスが含まれます (クリックするとフルサイズの画像が表示されます)

ステップ 1: 製品情報を一覧表示するページングされた GridView の追加

チェック ボックスの列の追加について説明する前にまず、ページングをサポートする GridView での製品の一覧表示に注目しましょう。 まず、EnhancedGridView フォルダー内の CheckBoxField.aspx ページを開き、ツールボックスからデザイナーに GridView をドラッグして、その IDProducts に設定します。 次に、ProductsDataSource という名前の新しい ObjectDataSource への GridView のバインドを選択します。 ProductsBLL クラスを使うように ObjectDataSource を構成し、GetProducts() メソッドを呼び出してデータを取得します。 この GridView は読み取り専用なので、[UPDATE]、[INSERT]、[DELETE] タブのドロップダウン リストを [(なし)] に設定します。

Create a New ObjectDataSource Named ProductsDataSource

図 2: ProductsDataSource という名前の 新しい ObjectDataSource を作成します (クリックするとフルサイズの画像が表示されます)

Configure the ObjectDataSource to Retrieve Data Using the GetProducts() Method

図 3: GetProducts() メソッドを使ってデータを取得するように ObjectDataSource を構成します (クリックするとフルサイズの画像が表示されます)

Set the Drop-Down Lists in the UPDATE, INSERT, and DELETE Tabs to (None)

図 4: [UPDATE]、[INSERT]、[DELETE] の各タブのドロップダウン リストを [(なし)] に設定します (クリックするとフルサイズの画像が表示されます)

データ ソースの構成ウィザードが完了すると、Visual Studio によって、製品関連のデータ フィールドに対して BoundColumns と CheckBoxColumn が自動的に作成されます。 前のチュートリアルで行ったように、ProductNameCategoryNameUnitPrice の各 BoundField 以外のすべてを削除し、HeaderText プロパティを Product、Category、Price に変更します。 値が通貨として書式設定されるように UnitPrice BoundField を構成します。 また、スマート タグの [ページングを有効にする] チェック ボックスをオンにして、ページングをサポートするように GridView を構成します。

選んだ製品を削除するためのユーザー インターフェイスも追加しましょう。 GridView の下に Button Web コントロールを追加し、その IDDeleteSelectedProducts に設定して、その Text プロパティを「Delete Selected Products」に設定します。 この例では、データベースから製品を実際に削除するのではなく、削除された製品を示すメッセージを表示するだけにします。 これに対応するには、ボタンの下に Label Web コントロールを追加します。 その ID を DeleteResults に設定し、Text プロパティをクリアして、VisibleEnableViewState プロパティを 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 個の製品の名前、カテゴリ、価格が表示されます。

The Name, Category, and Price of the First Ten Products are Listed

図 5: 最初の 10 製品の名前、カテゴリ、価格の一覧が表示されます (クリックするとフルサイズの画像が表示されます)

ステップ 2: チェック ボックスの列の追加

ASP.NET 2.0 には CheckBoxField が含まれるので、それを使ってチェック ボックスの列を GridView に追加できると思うかもしれません。 残念ながら、CheckBoxField はブール型のデータ フィールドを操作するように設計されているため、それはできません。 つまり、CheckBoxField を使うには、レンダリングされたチェック ボックスがオンになっているかどうかを判断するためにその値を調べる、基になるデータ フィールドを指定する必要があります。 CheckBoxField を使って、オフになっているチェック ボックスの列だけを含めることはできません。

代わりに、TemplateField を追加し、CheckBox Web コントロールをその ItemTemplate に追加する必要があります。 次に、Products GridView に TemplateField を追加して、最初 (左端) のフィールドにします。 GridView のスマート タグで [テンプレートの編集] リンクをクリックして、ツールボックスから ItemTemplate に CheckBox Web コントロールをドラッグします。 この CheckBox の ID プロパティを ProductSelector に設定します。

Add a CheckBox Web Control Named ProductSelector to the TemplateField s ItemTemplate

図 6: ProductSelector という名前の CheckBox Web コントロールを TemplateField の ItemTemplate に追加します (クリックするとフルサイズの画像が表示されます)

TemplateField と CheckBox Web コントロールを追加すると、各行に チェック ボックスが含まれるようになります。 図 7 で示されているのは、TemplateField と CheckBox を追加した後のこのページをブラウザーで表示したものです。

Each Product Row Now Includes a Checkbox

図 7: 製品の行ごとにチェック ボックスが含まれるようになっています (クリックするとフルサイズの画像が表示されます)

ステップ 3: ポストバックでのオンにされたチェック ボックスの判別

この時点では、チェック ボックスの列はありますが、ポストバックでオンにされたチェック ボックスを判別する方法がありません。 [Delete Selected Products] ボタンがクリックされたときに、それらの製品を削除するには、オンにされたチェック ボックスを知る必要があります。

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 オブジェクトごとに row.FindControl("controlID") を使って行の CheckBox にアクセスします。 CheckBox がオンの場合、行の対応する ProductID 値が DataKeys コレクションから取得されます。 この演習では DeleteResults Label に情報メッセージを表示するだけですが、実際のアプリケーションでは、代わりに ProductsBLL クラスの DeleteProduct(productID) メソッドを呼び出します。

このイベント ハンドラーを追加した後は、[Delete Selected Products] ボタンをクリックすると、選んだ製品の ProductID が表示されるようになります。

When the Delete Selected Products Button is Clicked the Selected Products ProductIDs are Listed

図 8: [Delete Selected Products] ボタンをクリックすると、選んだ製品の ProductID が表示されます (クリックするとフルサイズの画像が表示されます)

ステップ 4: [Check All] と [Uncheck All] ボタンの追加

ユーザーは、現在のページのすべての製品を削除したい場合、10 個のチェック ボックスを 1 つずつオンにする必要があります。 クリックするとグリッド内のすべてのチェック ボックスがオンになる [Check All] ボタンを追加して、このプロセスを簡単にできます。 [Uncheck All] ボタンも同様に役に立ちます。

2 つの Button Web コントロールをページに追加し、GridView の上に配置します。 1 つ目の IDCheckAll に設定し、その Text プロパティを「Check All」に設定します。2 つ目の IDUncheckAll に設定し、その Text プロパティを「Uncheck All」に設定します。

<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

次に、CheckAllUncheckAll ボタン用の Click イベント ハンドラーを作成します。 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

このコードでは、[Check All] ボタンをクリックするとポストバックが発生し、GridView のすべてのチェック ボックスがオンにされます。 同様に、[Uncheck All] をクリックすると、すべてのチェック ボックスがオフにされます。 図 9 では、[Check All] ボタンがクリックされた後の画面が示されています。

Clicking the Check All Button Selects All Checkboxes

図 9: [Check All] ボタンをクリックすると、すべてのチェック ボックスがオンになります (クリックするとフルサイズの画像が表示されます)

Note

チェック ボックスの列を表示するとき、すべてのチェック ボックスをオンまたはオフにする方法の 1 つは、ヘッダー行のチェック ボックスを使うことです。 さらに、現在の [Check All] と [Uncheck All] の実装にはポストバックが必要です。 ただし、チェック ボックスのオンとオフを、クライアント側スクリプトで完全に行うことができ、ユーザー エクスペリエンスがいっそう速くなります。 [Check All] と [Uncheck All] にヘッダー行チェック ボックスを使う方法の詳細と、クライアント側の手法の使用に関する説明については、クライアント側スクリプトとすべてをオンにする CheckBox を使用して GridView 内のすべての CheckBox をオンにする方法に関する説明をご覧ください。

まとめ

先に進む前にユーザーが GridView から任意の数の行を選択できるようにする必要がある場合は、チェック ボックスの列を追加するのが 1 つのオプションです。 このチュートリアルで見たように、GridView にチェック ボックスの列を含めるには、CheckBox Web コントロールを含む TemplateField を追加する必要があります。 (前のチュートリアルで行ったように、テンプレートにマークアップを直接挿入するのではなく) Web コントロールを使うと、ASP.NET はポストバックを通じてオンとオフの CheckBox を自動的に記憶します。 また、プログラムにより、コードで CheckBox にアクセスして、特定の CheckBox がオンかどうかを判断したり、オン状態を変更したりすることもできます。

このチュートリアルと最後のものでは、GridView に行セレクター列を追加する方法を見ました。 次のチュートリアルでは、少しの作業で GridView に挿入機能を追加する方法を調べます。

プログラミングに満足!

著者について

Scott Mitchell 氏は、ASP/ASP.NET に関する 7 冊の本の著者であり、4GuysFromRolla.com の設立者でもあります。1998 年以降、Microsoft の Web テクノロジを活用した業務を行っています。 Scott は、独立したコンサルタント、トレーナー、ライターとして働いています。 彼の最新の本は サムズは24時間で2.0 ASP.NET 自分自身を教えています。 にアクセスするか、ブログを使用して にアクセスmitchell@4GuysFromRolla.comできます。これは でhttp://ScottOnWriting.NET見つけることができます。