Shoeisha Technology Media

CodeZine(コードジン)

記事種別から探す

GridViewで再読み込みを行わずに表示ページを切り換える

GridViewのAjax設定を利用する

  • LINEで送る
  • このエントリーをはてなブックマークに追加
2006/10/13 00:00

ASP.NET 2.0のGridViewコントロールは、Ajaxのように再読み込みを行わずにデータの表示ページを切り換えることができます。いくつかの制限がある中で、この機能を使えるようにするための方法を紹介します。

目次

はじめに

 Webアプリケーションの世界では、「Ajax」と呼ばれる再読み込みを行わずに画面上の表示を書き換える技術が注目されています。この流れに合わせるように、ASP.NET 2.0で提供されているGridViewコントロールには、再読み込みを行わずにデータの表示ページを切り換える設定(EnableSortingAndPagingCallbacksプロパティ)が用意されています。

 ただし、このプロパティをtrueに設定して利用する場合には、TemplateFieldや選択ボタンが使えないという制限があります。ここでは、その制限の中でGridViewを利用するためにどうしたらよいかを考えてみましょう。

対象読者

 ASP.NETでWebアプリケーションを開発している方。

必要な環境

 Visual Web Developerなど。

GridViewの動きを確認する

 まずGridViewのEnableSortingAndPagingCallbacksプロパティをtrueに設定した場合の動作を確認してみましょう。最初にGridViewに表示するテーブルを以下の内容で作成します。このテーブルにはテスト用のデータを数件入力しておきます。

テーブル名:userTable
項目1userIDint主キー
項目2userNamenvarchar(50)Nullを不許可
項目3mailnvarchar(50)Nullを許可

 画面上には再読み込みが発生したかどうかを確認するために、時刻を表示するためのラベルと、上記のテーブルをドラッグ&ドロップして作成したGridViewを貼り付けます。GridViewは「ページング」「編集」「削除」を有効にし、EnableSortingAndPagingCallbacksプロパティを「true」に設定しておきます。

図1 GridViewの設定
図1 GridViewの設定

 コードを表示し、Page_Loadメソッドに以下のように入力して、画面が作成された時刻が表示されるようにします。

Page_Loadメソッド
protected void Page_Load(object sender, EventArgs e)
{
    this.Label1.Text = DateTime.Now.ToString();
}

 デバッグを実行し、動作を確認してみましょう。ページを変更しても画面上の時刻は変わらないことが、以下の2つの図を比較すると確認できます。

図2 1ページ目を表示
図2 1ページ目を表示
図3 2ページ目を表示
図3 2ページ目を表示

 このとき、[編集]や[削除]をクリックすると画面上の時刻が変わります。ここから、これらの作業を実行する際には、サーバへのPostBackが行われていることが分かります。

データの削除を確認できるようにする

 デバッグ時に[削除]をクリックすると、ただちにデータの削除が行われてしまいます。これではオペレーションのミスで重要なデータが消えてしまうことになりかねません。削除するかどうかを確認するメッセージを表示するようにしましょう。

 [削除]をクリックしたときにメッセージを表示させるには、[削除]リンクボタンのOnClientClickプロパティにJavaScriptを追加します。ただし、[削除]リンクボタンはCommandFieldによって実行時に生成されて表示されているリンクボタンなので、デザイン画面からプロパティの設定を行うことができません。TemplateFieldが使えるのであれば、CommandFieldをTemplateFieldに変換したうえで[削除]リンクボタンのプロパティを設定するという方法が使えるのですが、EnableSortingAndPagingCallbacksをtrueにした状態では、これはエラーになってしまいます。そこで、実行時にプログラムからプロパティの設定を行うことにします。

[削除]リンクボタン生成のしくみ

 まず、ターゲットとなる[削除]リンクボタンがどのように生成されているかを確認してみましょう。このためにページのTraceを有効にします。「プロパティ」ウィンドウで[DOCUMENT]を選択し、Traceプロパティを「true」に設定します。

図4 ページのTraceを有効にする
図4 ページのTraceを有効にする

 これはPageディレクティブにTrace="true"という記述を追加するのと同じ意味を持ちます。

 この状態でデバッグを実行してみましょう。「要求の詳細」「トレース情報」「コントロールのツリー」など、さまざまな情報が表示されますが、ここでは「コントロールのツリー」の中に注目します。

 GridViewには1つのChildTableが含まれており、ChildTableには以下の6つのGridViewRowが含まれています。

  • ヘッダー行
  • データ行(3行)
  • フッター行(非表示)
  • ページコントロール行

 そしてデータ行の先頭にはDataControlFieldCellがあり、そこに以下の3つのコントロールが存在しています。

  • DataControlLinkButton([編集]リンクボタン)
  • LiteralControl(半角空白)
  • DataControlLinkButton([削除]リンクボタン)
図5 コントロールのツリー
図5 コントロールのツリー

 [削除]リンクボタンの実体であるDataControlLinkButtonですが、ドキュメントには説明がありません。しかし、名前とその動作からLinkButtonコントロールから派生したコントロールではないかと推測できます。

プロパティを操作するプログラム

 さて、[削除]リンクボタンがどこでどのように生成されているかが分かったところで、そのプロパティを操作するプログラムを記述することにしましょう。このとき、プロパティを操作するタイミングをどのイベントが発生したときにするかを考える必要があります。ここではGridViewにデータが連結(バインド)されたときに発生するRowDataBoundイベントの中でプロパティを操作することにします。

 GridViewの「プロパティ」ウィンドウで、稲妻型のアイコンをクリックしてイベントの一覧を表示し、RowDataBoundイベントをダブルクリックします。GridView1_RowDataBoundメソッドが生成されるので、そこに以下のように記述します。

GridView1_RowDataBoundメソッド
protected void GridView1_RowDataBound(object sender,
                                      GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
        ((LinkButton)e.Row.Cells[0].Controls[2]).OnClientClick
            = "return confirm('削除してよろしいですか');";
}

 このプログラムでは、最初に今操作している行がデータ行かどうかを判定します。そしてデータ行だったら、最初のセル(Cells[0]:DataControlFieldCell)の中の3番目のコントロール(Controls[2]:DataControlLinkButton)を取り出し、そのコントロールをLinkButtonにキャストしてOnClientClickプロパティにJavaScript(文字列)を設定します。

 これでデバッグを開始してみましょう。推測通り、DataControlLinkButtonはLinkButtonから派生したコントロールだったようで、キャストによるエラーはありません。表示される画面上で[削除]をクリックすると、以下の確認画面が表示されます。

図6 削除の確認画面
図6 削除の確認画面

 さて、ここで[編集]をクリックしてデータの編集モードを表示し、[キャンセル]をクリックしてみましょう。すると、[削除]をクリックしたときと同じように確認画面(図6)が表示されてしまいます。これは、データ行の最初のセルにある3番目のコントロールのOnClientClickプロパティに、常にJavaScriptを設定してしまっているからです。

 データ行が編集モードのときにはJavaScriptを設定しないよう、GridView1_RowDataBoundメソッドを次のように修正しておきましょう。

GridView1_RowDataBoundメソッド
protected void GridView1_RowDataBound(object sender,
                                      GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
        if (e.Row.RowIndex != GridView1.EditIndex)  // この条件文を追加
            ((LinkButton)e.Row.Cells[0].Controls[2]).OnClientClick
            = "return confirm('削除してよろしいですか');";
}

  • LINEで送る
  • このエントリーをはてなブックマークに追加

著者プロフィール

  • 小野 修司(オノ シュウジ)

    MVP for Visual Developer - Visual C# あおい情報システム株式会社勤務。 .NETに関する話題を扱う「どっとねっとふぁん」を運営。  

おすすめ記事

All contents copyright © 2006-2017 Shoeisha Co., Ltd. All rights reserved. ver.1.5