はじめに
Webサイトでよく目にするユーザーインターフェイスのパターンとして、各行にチェックボックスが付いている項目のリストがあります。その典型的な例が、WebベースのEメールクライアントによく見られる、チェックボックスをオンにすることで操作対象のメッセージを選択するというユーザーインターフェイスです。選択した1つ以上のEメールに対し、ユーザーはメッセージの削除、開封済みのマーキング、別フォルダへの移動などのアクションを適用することができます。このようなユーザーインターフェイスの多くは、チェックボックスを1つずつオンにする機能のほかに、[すべて選択]というチェックボックスをヘッダー行に用意しています。このチェックボックスをオンまたはオフにすると、その下にあるリスト内のすべての項目のチェックボックスが自動的にオンまたはオフになります。
このようなユーザーインターフェイスをASP.NET 2.0のGridViewコントロールで作成することは十分に可能であり、これが本稿のテーマです。特に、サーバーサイドコードとクライアントサイドスクリプトを使って「すべて選択(Check All)」と「すべて選択解除(Uncheck All)」の両方の機能を実現する方法を解説します。サーバーサイドコードを使う方がかなり簡単ですが、すべてのチェックボックスをオンまたはオフにすることを選んだときにポストバックが要求されます。それに対し、クライアントサイドのアプローチでは、ユーザーインターフェイスの反応が速くスムーズになりますが、正しく実装するには少し工夫が必要になります。
土台作り:各行にチェックボックスを備えたGridViewを作成する
GridView内のチェックボックスをオンまたはオフにする機能をどうやって実現するかを説明する前に、まず各行にチェックボックスを備えたGridViewコントロールを作成するにはどうするかを考えてみましょう。GridViewにチェックボックスの列を追加するには、次の2つのアプローチのいずれかを使います。
- CheckBoxFieldを使う -- CheckBoxFieldは、チェックボックス(CheckBox)の列をレンダリングする組み込み型のGridViewフィールドです。各CheckBoxの
Checked
プロパティは、グリッドの基礎となるデータソース内の何らかのデータフィールドに関連付けられます。 - TemplateFieldを使う -- TemplateFieldを追加して、項目テンプレート(
ItemTemplate
)内にCheckBox Webコントロールを追加することができます。CheckBox WebコントロールのChecked
プロパティを何らかのデータフィールド値に関連付ける必要がある場合は、<asp:CheckBox runat="server" ... Checked='<%# Eval("ColumnName") %>' ... />
などの宣言を使用するか、RowDataBoundイベントハンドラなどを使用してChecked
プロパティを設定できます。
2つ目のTemplateFieldを使う方法には利点がたくさんあります。まず、カスタマイズ性に優れています。各行にマークアップを追加することはもちろん、カスタムヘッダーを提供することも簡単です。実際、本稿のサンプルでは、この列のヘッダーにチェックボックスを置き、ユーザーがそれを使ってGridView上のすべてのチェックボックスをオンまたはオフにできるようにしています。詳細については、『Checking All CheckBoxes in a GridView Using Client-Side Script and a Check All CheckBox』を参照してください。また、CheckBoxのChecked
プロパティを、基礎となるデータフィールドに依存させない場合は、TemplateFieldの方法を使う必要があります。本稿では、TemplateFieldを使うことにします。
本稿で紹介するサンプルは、Webベースのファイル管理ツールです。このインターフェイスには、現在のディレクトリに含まれているファイルの名前と、各ファイルに対するチェックボックスを表示します。このGridViewの後に、[Delete Checked Files]ボタンを追加します。このボタンをクリックすると、チェックボックスがオンになっているファイルがファイルシステムから削除されます(本稿のサンプルでは、ファイルは実際には削除されず、その機能が実装された場合にどのファイルが削除されるかを示すメッセージが表示されるだけです)。
必要な機能を追加したGridViewを次に示します。ここでは、TemplateFieldを使用することでGridViewの各行にCheckBoxコントロールを追加しています(簡潔にするため、GridViewのフォーマット関連の設定は一部省略しました)。
<asp:GridView ID="FileList" runat="server" AutoGenerateColumns="False" DataKeyNames="FullName"> <Columns> <asp:TemplateField> <ItemTemplate> <asp:CheckBox runat="server" ID="RowLevelCheckBox" /> </ItemTemplate> </asp:TemplateField> <asp:BoundField DataField="Name" HeaderText="Name" /> <asp:BoundField DataField="CreationTime" HeaderText="Created On"> <ItemStyle HorizontalAlign="Right" /> </asp:BoundField> <asp:BoundField DataField="Length" DataFormatString="{0:N0}" HeaderText="File Size" HtmlEncode="False"> <ItemStyle HorizontalAlign="Right" /> </asp:BoundField> </Columns> </asp:GridView>
現在のディレクトリ内のファイルにアクセスしてGridViewにバインドする処理は、Page_Load
イベントハンドラ内に記述します。
Protected Sub Page_Load(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles Me.Load If Not Page.IsPostBack Then Dim dirInfo As New DirectoryInfo(Request.PhysicalApplicationPath) FileList.DataSource = dirInfo.GetFiles() FileList.DataBind() End If End Sub
ディレクトリ内のファイルの一覧を表示する方法については、『Displaying the Files in a Directory Using a DataGrid』を参照してください。
次に必要なのは、[Delete Checked Files]ボタンです。このボタンがクリックされたときに、オンの状態のチェックボックスを判別して、対応するファイルを削除する必要があります。このボタンのClick
イベントハンドラでは、GridViewのRows
コレクション内を反復処理し、個々のGridViewRow
インスタンスについて、RowLevelCheckBox
がオンになっているかどうかを判別します。オンになっている場合は、そのファイルパスをLabel Webコントロール(Summary
)に連結します(実際に動作するアプリケーションでは、System.IO
名前空間内のFile.Delete(path)
メソッドを使ってファイルを削除する必要があります)。
Protected Sub DeleteButton_Click(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles DeleteButton.Click Summary.Text = "The following file would have been deleted:<ul>" Dim currentRowsFilePath As String 'Enumerate the GridViewRows For index As Integer = 0 To FileList.Rows.Count - 1 'Programmatically access the CheckBox from the TemplateField Dim cb As CheckBox = CType(FileList.Rows(index). _ FindControl("RowLevelCheckBox"), CheckBox) 'If it's checked, delete it... If cb.Checked Then currentRowsFilePath = FileList.DataKeys(index).Value Summary.Text &= String.Concat( _ "<li>", currentRowsFilePath, "</li>") End If Next Summary.Text &= "</ul>" End Sub
TemplateFieldからCheckBoxを参照するときの構文FileList.Rows(index).FindControl("controlID")
に注意してください。CheckBoxFieldを使用した場合は、この構文はFileList.Rows(index).Cells(0).Controls(0)
になります。Cells(0)
は指定された行の最初の列を表し(ここでは、CheckBoxFieldがGridViewの最初のフィールドであると想定しています)、Control(0)
はその列のControls
コレクション内での最初のコントロール、つまりCheckBoxFieldの場合はCheckBoxコントロールを表します。
土台作りはこれで終わりです。次に、GridView上のすべてのチェックボックスをオンまたはオフにする機能の実装方法を説明します。まず、サーバーサイドコードを使ってこの機能を実現する方法を解説します。