WebSurfer's Home

トップ > Blog 1   |   ログイン
APMLフィルター

GridView の最終ページに空行追加

by WebSurfer 2015年7月7日 16:14

GridView と SqlDataSource を使用してページングを行う際、最終ページの行数が PageSize より少ない場合、最終データ行の次に即ページャー行が表示されます。(下の画像のように空行は表示されません)

最終ページに空行を挿入

それを、上の画像のように空行を挿入(例えば、PageSize が 10 で、最終ページのデータ行が 7 行の場合、空のデータ行を 3 行追加する)する方法を書きます。

自力でコードを書いて DataTable を作って、それを GridView にデータバインドしているような場合は、DataTable に空行を追加するのが簡単そうですが、GridView と SqlDataSource を組み合わせて使っているような場合はその手が使えません。(ウラワザ的なことをすれば話は別かもしれませんが)

なので、DataTable を細工するのは諦めて、GridView.RowCreated イベントでデータ行の行数を調べ、それが PageSize より少ない場合は空の GridViewRow を追加する方法を取ってみました。

簡単に書くと、(1) ヘッダ行で RowCreated イベントが発生した際にそのセル数を取得。[ヘッダ行のセル数] = [データ行のセル数] というのが前提です、(2) ページャー行で RowCreated イベントが発生した際、[データ行] < [PageSize] であればその差の分空のデータ行を生成し GridView に追加する・・・ということです。

そのコードは以下のようになります。コメントに上記 (1), (2) の詳細を書きましたので見てください。データベースは、Microsoft が提供しているサンプル Northwind の Products テーブルを使っています。

<%@ Page Language="C#" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">

  // データ行のセル数
  int numberOfCells = 0;
    
  protected void GridView1_RowCreated(object sender, 
                                      GridViewRowEventArgs e)
  {
    if (e.Row.RowType == DataControlRowType.Header)
    {
      // ヘッダ行のセル数=データ行のセル数が前提
      numberOfCells = e.Row.Cells.Count;
    }        
    else if (e.Row.RowType == DataControlRowType.DataRow)
    {
      // データ行では何もしない
    }
    else if (e.Row.RowType == DataControlRowType.Footer)
    {
      // フッタ行でも何もしない。ページャー行よりこち
      // らの方のイベント発生が先になるが
    }
    else if (e.Row.RowType == DataControlRowType.Pager)
    {
      // AllowPaging="False" に設定されているとここに
      // 制御は飛んでこない。なので、データ行追加の小
      // 細工はここで行った方がよさそう。
            
      GridView gridView = (GridView)sender;
      int numberOfRows = gridView.Rows.Count;
      int pageSize = gridView.PageSize;

      // データ行 < PageSize の場合、その差の分だけ
      // 空のデータ行とその中身(空セル)を生成
      for (int i = numberOfRows; i < pageSize; i++)
      {
        GridViewRow row = new GridViewRow(
                i,
                -1,
                DataControlRowType.DataRow,
                DataControlRowState.Normal);

        for (int j = 0; j < numberOfCells; j++)
        {
          TableCell cell = new TableCell();
          row.Cells.Add(cell);
        }

        // 空のデータ行を GridView に追加。
        // Collection の中の順番は Footer/Pager 行の
        // 後になるが、HTML にレンダリングされる時は
        // 期待した順序になる。上の GridViewRow のコ
        // ンストラクタで設定した i (RowIndex) と
        // DataControlRowType.DataRow を見ている?
        gridView.Controls[0].Controls.Add(row);
      }           
    }
  }
</script>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
  <title></title>
  <style type="text/css">
      table tr
      {
        /* 行(空行を含む)の高さ設定 */
        height: 30px;
      }    
  </style>
</head>
<body>
  <form id="form1" runat="server">
  <div>
    <asp:SqlDataSource ID="SqlDataSource1" 
      runat="server" 
      ConnectionString="<%$ ConnectionStrings:Northwind %>" 
      SelectCommand="SELECT * FROM [Products]">
    </asp:SqlDataSource>

    <asp:GridView ID="GridView1" runat="server" 
      AllowPaging="True" 
      AutoGenerateColumns="False" 
      DataKeyNames="ProductID" 
      DataSourceID="SqlDataSource1" 
      OnRowCreated="GridView1_RowCreated">
      <Columns>
        <asp:BoundField DataField="ProductID" 
          HeaderText="ProductID" InsertVisible="False" 
          ReadOnly="True" SortExpression="ProductID" />
        <asp:BoundField DataField="ProductName" 
          HeaderText="ProductName" 
          SortExpression="ProductName" />
        <asp:BoundField DataField="SupplierID" 
          HeaderText="SupplierID" 
          SortExpression="SupplierID" />
        <asp:BoundField DataField="CategoryID" 
          HeaderText="CategoryID" 
          SortExpression="CategoryID" />
        <asp:BoundField DataField="QuantityPerUnit" 
          HeaderText="QuantityPerUnit" 
          SortExpression="QuantityPerUnit" />
        <asp:BoundField DataField="UnitPrice" 
          HeaderText="UnitPrice" 
          SortExpression="UnitPrice" />
        <asp:BoundField DataField="UnitsInStock" 
          HeaderText="UnitsInStock" 
          SortExpression="UnitsInStock" />
        <asp:BoundField DataField="UnitsOnOrder" 
          HeaderText="UnitsOnOrder" 
          SortExpression="UnitsOnOrder" />
        <asp:BoundField DataField="ReorderLevel" 
          HeaderText="ReorderLevel" 
          SortExpression="ReorderLevel" />
        <asp:CheckBoxField DataField="Discontinued" 
          HeaderText="Discontinued" 
          SortExpression="Discontinued" />
      </Columns>
    </asp:GridView>
  </div>
  </form>
</body>
</html>

Tags:

Paging

About this blog

2010年5月にこのブログを立ち上げました。主に ASP.NET Web アプリ関係の記事です。

Calendar

<<  2024年3月  >>
252627282912
3456789
10111213141516
17181920212223
24252627282930
31123456

View posts in large calendar