■GridViewを並べ替えたときに選択されている行を保持する (GridView03StepUp1.aspx)
GridViewから[選択]ボタンをクリックして行を選択した状態で列を並べ替えたときに、選択した行を保持するサンプルを作成します。このサンプルでは、以下のノウハウを習得することができます。
▼ GridViewのDataBoundイベントハンドラの使い方
▼ GridViewのPageIndexChangingイベントハンドラの使い方
▼ GridViewのSortingイベントハンドラの使い方
▼ GridViewのSelectedIndexChangedイベントハンドラの使い方
▼ ViewStateに値を保存したり取り出す方法


図 行を選択した後に並べ替えしても選択した行が保持される
1. 新規Webページ作成
ソリューションエクスプローラのプロジェクトの右クリックから[新しい項目の追加]を選択して、新規Webページ「GridView03StepUp1.aspx」を作成します。
2. コントロール作成
GridView03.aspxのデザイナならGridView1とSqlDataSource1のオブジェクトをコピーしたら、GridView03StepUp1.aspxのデザイナに貼り付けします。デザイナにGridView1とSqlDataSource1のオブジェクトが作成されたら、「GridViewタスク」から「選択を有効にする」をチェックします。「GridViewタスク」から[列の編集]を選択して、「フィールド」ダイアログを表示します。「選択されたフィールド」から[選択]のフィールドをクリックしたら、CommandFieldプロパティからButtonTypeプロパティに[Button]を設定して[OK]をクリックします。
3. イベントハンドラ追加
デザイナの右クリックから[コードの表示]を選択します。コードビューが表示されたら、「(全般)」のドロップダウンリストから[GridView1]を選択します。「(宣言)」のドロップダウンリストから[DataBound]、[SelectedIndexChanged]、[PageIndexChanging]、[Sorting]を選択して、これらのイベントハンドラを生成したら、次のコードを追加します。
Protected Sub GridView1_DataBound(ByVal sender As Object, ByVal e As System.EventArgs) Handles GridView1.DataBound
Dim strSelectedValue As String = CType(ViewState("SelectedValue"), String)
If IsNothing(strSelectedValue) Then
Return
End If
For Each Row As GridViewRow In GridView1.Rows
Dim strKeyValue As String = CType(GridView1.DataKeys(Row.RowIndex).Value, String)
If strKeyValue = strSelectedValue Then
GridView1.SelectedIndex = Row.RowIndex
End If
Next
End Sub
Protected Sub GridView1_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles GridView1.SelectedIndexChanged
If GridView1.SelectedIndex <> -1 Then
ViewState("SelectedValue") = GridView1.SelectedValue
End If
End Sub
Protected Sub GridView1_PageIndexChanging(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewPageEventArgs) Handles GridView1.PageIndexChanging
GridView1.SelectedIndex = -1
End Sub
Protected Sub GridView1_Sorting(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewSortEventArgs) Handles GridView1.Sorting
GridView1.SelectedIndex = -1
End Sub
4. ブラウザに表示
VWD 2005のツールバーから[デバッグの開始]ボタンをクリックしてブラウザに表示します。ブラウザが起動されて、GridViewにCustomersテーブルが表示されます。GridViewから得意先IDが「5」の[選択]ボタンをクリックして行を選択します。次に、GridViewのヘッダーから[ID]を2回クリックして降順に並べ替えします。GridViewのページャーから[5]をクリックして最終ページに移動すると、得意先ID「5」の行が選択された状態になっています。

図 選択した行が並べ替えしても保持される
◆解説
GridViewから選択した行を並べ替えしても保持するには、選択した行の主キーをViewStateに保存してGridViewが再表示されるときに復元します。
GridViewから行を選択したときレコードの主キーを取得するには、GridViewにSelectedIndexChangedイベントハンドラを追加します。このイベントハンドラでは、GridViewのSelectedIndexプロパティを調べて行が選択されているかチェックします(選択されているときは「-1」以外が格納されている)。行が選択されているときは、GridViewのSelectedValueプロパティに格納されている主キー(CustomerID)を取得してViewStateに保存します。
ViewStateに主キーを保存すると、Webページがポストバックされても内容が保持されます。ViewStateに主キーを保存するには、Addメソッドを使用します。Addメソッドの引数には、キーと値を指定します。Addメソッドを省略してViewStateの引数に直接キーを指定して記述することもできます。
ViewState.Add(key:="SelectedValue", value:=GridView1.SelectedValue)
ViewState("SelectedValue") = GridView1.SelectedValue
Protected Sub GridView1_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles GridView1.SelectedIndexChanged
If GridView1.SelectedIndex <> -1 Then
ViewState("SelectedValue") = GridView1.SelectedValue
End If
End Sub
GridViewを並べ替えした後に選択されて行を復元するには、GridViewにDataBoundイベントハンドラを追加します。このイベントハンドラでは、ViewStateから選択した行の主キーを取得して変数に保存します。For Each …Nextでは、GridViewのRowsコレクションからGridViewRowを取得してDataKeysコレクションに格納されている主キーを検索します。一致する主キーを見つけたら、SelectedIndexプロパティにRowIndexプロパティの値を設定してこの行を選択行とします。GridViewRowのRowIndexにはレコードの行番号が格納されています。
GridViewのDataKeysコレクションに主キーを格納するには、DataKeyNameプロパティに主キーのフィールド名を設定する必要があります。このプロパティは、SqlDataSourceを作成するときテーブルから主キーのフィールド(CustomerID)を選択すると自動的に設定されます。
<asp:GridView ID="GridView1" runat="server"
AllowPaging="True" AllowSorting="True"
DataKeyNames="CustomerID"・・・>
・・・
</asp:GridView>
Protected Sub GridView1_DataBound(ByVal sender As Object, ByVal e As System.EventArgs) Handles GridView1.DataBound
Dim strSelectedValue As String = CType(ViewState("SelectedValue"), String)
If IsNothing(strSelectedValue) Then
Return
End If
For Each Row As GridViewRow In GridView1.Rows
Dim strKeyValue As String = CType(GridView1.DataKeys(Row.RowIndex).Value, String)
If strKeyValue = strSelectedValue Then
GridView1.SelectedIndex = Row.RowIndex
End If
Next
End Sub
GridViewのPageIndexChangingとSortingイベントハンドラでは、GridViewのSelectedIndexプロパティに「-1」を設定して現在されている行を無効(通常行に戻す)にします。
Protected Sub GridView1_PageIndexChanging(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewPageEventArgs) Handles GridView1.PageIndexChanging
GridView1.SelectedIndex = -1
End Sub
Protected Sub GridView1_Sorting(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewSortEventArgs) Handles GridView1.Sorting
GridView1.SelectedIndex = -1
End Sub