Check All/Uncheck All機能をサーバーサイドコードで実現する
Check All/Uncheck All機能を実現するために、先ほどのGridViewにButton Webコントロールを2つ追加します。
<p> <asp:Button ID="CheckAll" runat="server" Text="Check All" /> <asp:Button ID="UncheckAll" runat="server" Text="Uncheck All" /> </p>
次に、両方のButtonコントロールのClickイベントハンドラに必要なコードを記述します。具体的には、GridViewのRowsコレクションを反復処理し、各GridViewRowインスタンスのCheckBoxにアクセスし、それぞれのボタンの機能に合わせてCheckedプロパティを設定します。
Protected Sub CheckAll_Click(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles CheckAll.Click 'Enumerate each GridViewRow For Each gvr As GridViewRow In FileList.Rows 'Programmatically access the CheckBox from the TemplateField Dim cb As CheckBox = CType( _ gvr.FindControl("RowLevelCheckBox"), CheckBox) 'Check it! cb.Checked = True Next End Sub Protected Sub UncheckAll_Click(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles UncheckAll.Click 'Enumerate each GridViewRow For Each gvr As GridViewRow In FileList.Rows 'Programmatically access the CheckBox from the TemplateField Dim cb As CheckBox = CType( _ gvr.FindControl("RowLevelCheckBox"), CheckBox) 'Uncheck it! cb.Checked = False Next End Sub
これで終わりです。サーバーサイドのアプローチの唯一の問題は、Check All/Uncheck All機能を実行するとポストバックが発生し、その結果としてオーバーヘッドやスクリーンフラッシュが生じることです。このような動作はイントラネット環境では目立ちませんが、インターネットのサイトでは、クライアントサイドスクリプトを使って反応速度をできるだけ速くしようとする努力が一般に行われています。クライアントサイドスクリプトでこのような機能を実現する場合は、少し工夫が必要です。クライアントサイドスクリプト機能の説明に移る前に、サーバーサイドのアプローチの実際のスクリーンショットを見てください。[Check All]ボタンまたは[Uncheck All]ボタンをクリックすると、それに応じて、GridView内のすべてのチェックボックスがオンまたはオフになります。次のスクリーンショットは、[Check All]ボタンをクリックした直後の状態です。

Check All/Uncheck All機能をクライアントサイドスクリプトで実現する
反応をもっと速くするためには、Check All/Uncheck All機能でポストバックを発生させずに、クライアントサイドですべてのチェックボックスをオンまたはオフにすることが理想です。クライアントサイドのJavaScriptを使ってGridView上のチェックボックスにアクセスするには次のパターンを使います。
// Get a reference to the CheckBox var cb = document.getElementById('checkBoxID'); // Adjust the checked state cb.Checked = false; // or whatever...
checkBoxIDは、レンダリングするCheckBoxコントロールのクライアントサイドIDを表しています。これは、CheckBox WebコントロールのIDプロパティの値と必ずしも同じではありません。それどころか、クライアントサイドIDの先頭には、CheckBox Webコントロールの親コントロールのIDが付きます。クライアントサイドスクリプトでCheckBoxを扱うためには、GridView上の一連のCheckBoxのクライアントサイドIDを格納するクライアントサイド配列を作成する必要があります。
ASP.NET 2.0のClientScriptManagerクラスには、ASP.NETページからClientScriptプロパティを使って直接アクセスできるメソッドが数多く用意されています。このクラスには、ASP.NET 1.xのPageクラスと同じクライアントスクリプト関連のメソッドのほか、追加メソッドもいくつか含まれています。1.xと2.0に共通するメソッドの一つに、RegisterArrayDeclaration(arrayName, arrayValue)があります。このメソッドは、arrayValue入力パラメータで指定された要素のクライアントサイド配列を作成します(1つの配列に複数の要素を追加するには、RegisterArrayDeclaration(arrayName, arrayValue)を繰り返し呼び出して、同じarrayName値を渡します)。
次のコードでは、GridViewのRowsコレクションを反復処理し、各GridViewRowインスタンスのCheckBoxにアクセスし、そのクライアントサイドID(ClientIDプロパティで取得可能)をクライアントサイド配列(ClientSideIDs)に格納します。
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 'On every page visit we need to build up the CheckBoxIDs array For Each gvr As GridViewRow In FileList.Rows 'Get a programmatic reference to the CheckBox control Dim cb As CheckBox = CType( _ gvr.FindControl("RowLevelCheckBox"), CheckBox) ClientScript.RegisterArrayDeclaration("CheckBoxIDs", _ String.Concat("'", cb.ClientID, "'")) Next End Sub
このコードにより、ページに次のようなJavaScriptが追加されます。
<script type="text/javascript"> <!-- var CheckBoxIDs = new Array('<i>CheckBoxID1</i>', '<i>CheckBoxID2</i>', ... ,'<i>CheckBoxIDN</i>'); // --> </script>
クライアントサイドで挿入されるこのようなタイプの配列は次のポストバックまで残らないので、このコードはPage_Loadイベントハンドラに置き、ページアクセスがあるたびに実行する必要があります。このクライアントサイド配列を初めてページを読み込んだとき(またはGridViewがデータバインドされるとき)にのみ作成した場合は、[Delete Checked Files]ボタンのクリックなどによってポストバックが発生したときに、以降のページ読み込みでクライアントサイド配列CheckBoxIDsが組み込まれません(そのため、Check All/Uncheck All機能のレンダリングが適切に行われなくなります)。
サーバーサイドコードからクライアントサイドスクリプトを操作する方法の詳細については、『Working With Client-Side Script』を参照してください。
このクライアントサイドIDの配列を利用することで、この配列の要素を反復処理し、各要素のチェックボックスを参照し、その結果に従ってcheckedプロパティを設定するクライアントサイドスクリプトを作成することができます。今回の例では、この処理を行うために次の2つの関数を作成しました。
ChangeCheckBoxState(id, checkState)ChangeAllCheckBoxStates(checkState)
document.getElementById(id)を使って)参照し、そのcheckedプロパティをcheckStateパラメータの値に設定します。CheckBoxIDs配列内を反復処理し、それぞれの要素についてChangeCheckBoxStateを呼び出して、現在の要素のクライアントサイドID値とcheckStateパラメータの値を渡します。 次に、[Check All]ボタンと[Uncheck All]ボタンを表す2つの<input type="button" ... />をページに追加し、各ボタンのクライアントサイドのonclickイベントからChangeAllCheckBoxStatesを呼び出して、checkStateパラメータに適切な値を渡すようにします。
<script type="text/javascript"> function ChangeCheckBoxState(id, checkState) { var cb = document.getElementById(id); if (cb != null) cb.checked = checkState; } function ChangeAllCheckBoxStates(checkState) { // Toggles through all of the checkboxes // defined in the CheckBoxIDs array // and updates their value to the checkState input parameter if (CheckBoxIDs != null) { for (var i = 0; i < CheckBoxIDs.length; i++) ChangeCheckBoxState(CheckBoxIDs[i], checkState); } } </script> ... <p> <input type="button" value="Check All" onclick="ChangeAllCheckBoxStates(true);" /> <input type="button" value="Uncheck All" onclick="ChangeAllCheckBoxStates(false);" /> </p>
これらの変更を加えることで、[Check All]ボタンと[Uncheck All]ボタンがクライアントサイドだけでタスクを実行するようになり、インターフェイスの反応速度が向上します。本稿のサンプルアプリケーションでは、クライアントサイドのコード例を拡張して、チェックボックスの列のヘッダーにすべてのチェックボックスをオフまたはオフにするチェックボックスを含めています。この拡張例の詳細については、『Checking All CheckBoxes in a GridView Using Client-Side Script and a Check All CheckBox』を参照してください。
まとめ
本稿では、GridViewコントロール上のすべてのチェックボックスをオンまたはオフにする2つの方法を解説しました。これは、サーバーサイドコードを使えば非常に簡単に実現できますが、ポストバックというコストが生じます。クライアントサイドのアプローチではインターフェイスの反応速度を改善できますが、コードを工夫してJavaScript機能を追加する必要があります。
それでは、ハッピープログラミング!
