WebSurfer's Home

トップ > Blog 1   |   Login
Filter by APML

GridView の Pager に総レコード数を表示

by WebSurfer 6. December 2014 18:26

以下の画像のように、ページングが有効になっている GridView の Pager 内に「総レコード数」を表示するにはどうしたらいいかということを書きます。

Pager に総レコード数を表示

ListView と DataPager を利用する場合は、先の記事 ListView でページ指定 のサンプルコードのように Container.TotalRowCount で総レコード数が取得できます。(注:Container は DataPager オブジェクトを参照しています)

しかしながら、GirdView を利用した場合、ページング機能は GirdView に統合されているものを利用することになり、それから「総レコード数」を取得するプロパティなどはありません。

GridView は、データーソースコントロール(SqlDataSource または ObjectDataSource)と組み合わせて使うケースがほとんどだと思いますが、その場合はデーターソースコントロールの Selected イベントのハンドラを使って「総レコード数」を取得するのが簡単そうです。

例えば、データーソースコントロールに SqlDataSource を使う場合、その Selected イベントのハンドラの引数 SqlDataSourceStatusEventArgs クラスAffectedRows プロパティ から総レコード数を取得できます。

取得した「総レコード数」をページャーの中に表示するには、GridView.RowDataBound イベント のハンドラでページャーの行を探して、その中に追加します。

ページャーそのものはデフォルトで(何も設定しなくても) 1 2 3 4 5 6 7 8 9 10 ... というようなクリックするとその番号のページに飛べるハイパーリンクが生成されますが、PagerSettings クラス を使うともう少し細かな設定ができます。

上の画像のページャーは、PagerSettings クラスの Mode プロパティを NumericFirstLast に、PageButtonCount プロパティを 5 に設定した場合のものです。

SqlDataSource と GridView を使った場合のサンプル(上の画像のページを表示したもの)を以下にアップしておきます。

<%@ 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 GridView3TotalCount = 0;
    
  protected void SqlDataSource1_Selected(
        object sender, SqlDataSourceStatusEventArgs e)
  {
      GridView3TotalCount = e.AffectedRows;
  }

  protected void GridView3_RowDataBound(
        object sender, GridViewRowEventArgs e)
  {
    if (e.Row.RowType == DataControlRowType.Pager)
    {
      Label label = new Label();
      label.Text = "総レコード数: " + 
            GridView3TotalCount.ToString();
      e.Row.Cells[0].Controls.AddAt(0, label);
    }
  }
</script>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>GridView Total Records</title>
</head>
<body>
  <form id="form1" runat="server">
    <asp:SqlDataSource ID="SqlDataSource1" runat="server" 
      ConnectionString="<%$ ConnectionStrings:Northwind %>" 
      SelectCommand="SELECT * FROM [Orders]" 
      OnSelected="SqlDataSource1_Selected">
    </asp:SqlDataSource>

    総レコード数: <%=GridView3TotalCount%>
    <asp:GridView ID="GridView3" runat="server" 
      AllowPaging="True" 
      AutoGenerateColumns="False" 
      DataKeyNames="OrderID" 
      DataSourceID="SqlDataSource1" 
      OnRowDataBound="GridView3_RowDataBound">
      <PagerSettings 
        Mode="NumericFirstLast" 
        PageButtonCount="5">
      </PagerSettings>
      <Columns>
        <asp:BoundField DataField="OrderID" 
          HeaderText="OrderID" 
          InsertVisible="False" 
          ReadOnly="True" 
          SortExpression="OrderID" />
        <asp:BoundField DataField="CustomerID" 
          HeaderText="CustomerID" 
          SortExpression="CustomerID" />
        <asp:BoundField DataField="OrderDate" 
          HeaderText="OrderDate" 
          SortExpression="OrderDate" 
          DataFormatString="{0:yyyy/MM/dd}" />
        <asp:BoundField DataField="Freight" 
          HeaderText="Freight" 
          SortExpression="Freight" 
          DataFormatString="${0:N2}" />
        <asp:BoundField DataField="ShipCountry" 
          HeaderText="ShipCountry" 
          SortExpression="ShipCountry" />
      </Columns>
    </asp:GridView>
  </form>
</body>
</html>

データーソースコントロールに ObjectDataSource を使う場合も、ObjectDataSource.Selected イベントのハンドラ で「総レコード数」を取得できます。

ObjectDataSource を使う場合、ページを切り替えるたびに全レコードを DB から再度取得するという無駄なことを避けるため、普通は、先の記事 ObjectDataSource でページング に書いてあるように、必要なレコードのみ DB から取得するクラス/メソッドを実装して、それらを ObjectDataSource で定義されているプロパティに設定することになると思います。

上に紹介した記事のサンプルコードでは、GetDataByIndex と GetNumberOfMessages の 2 つのメソッドが ObjectDataSource に設定されていますが、その両方が呼ばれ、それぞれで Selected イベントが発生します(2 回 Selected イベントが発生します)。

その際、イベントハンドラの引数 ObjectDataSourceStatusEventArgs の ReturnValue プロパティ でそれぞれのメソッドが返すオブジェクトを取得できます。

したがって、e.ReturnValue が Int32 型にキャストできれば GetNumberOfMessages が返したもの、即ち全レコード数ということになります。なので、イベントハンドラのコードを以下のようにすれば「総レコード数」を取得できます。

protected void ObjectDataSource1_Selected(object sender, 
                        ObjectDataSourceStatusEventArgs e)
{
  if (e.ReturnValue is Int32)
  {
    GridView3TotalCount = (Int32)e.ReturnValue;
  }
}

「総レコード数」さえ取得できれば、あとは GridView と Pager の実装を SqlDataSource を使った場合と同様にして Pager に表示できます。

Tags: ,

Paging

ObjectDataSource でページング

by WebSurfer 26. August 2010 12:00

DB のレコード一覧を表示する場合、レコード数が多い場合はページングが必要になってきます。

SqlDataSource を使って、ウィザードベースでクエリなどを設定していけば、コードを一行も書くことなく簡単にページング機能を実装できます。

しかしながら、ウィザードベースで実装した場合は、ページを切り替えるたびに全レコードを取得し、そのページの当該部分のみを表示するという動作になります。

レコード数が多い場合、ページングの都度全レコードを取得するのは負荷が大きく、できれば避けたい操作です。

ちなみに、先の記事 カスタムページャー で紹介した Repeater とカスタムページャーを使用したページングではそのあたりは考慮してあります。

今回は、先の記事と同等な内容を、ObjectDataSource と ListView を使って実現する例を書いてみます。実行結果は以下のようになります。

ListVie でのページング

ポイントは、先の記事のようなストアドプロシージャを使うのではなくて、必要なレコードのみ DB から取得するクラス/メソッドを実装して、それらを ObjectDataSource で定義されているプロパティに設定するというところです。

加えて、出来るだけ ObjectDataSource と ListView が持つページングの機能を利用し、自力でコードは書かない(上記のクラス/メソッドを除く)ということもあります。

まず、型付 DataSet + TableAdapter(xsd ファイル)を Visual Studio のウィザードを利用して作成します。

Microsoft が提供しているサンプルデータベース Northwind の Products テーブルを利用します。ウィザードに従って進めていくと xsd ファイルが作られ、これをベースに 型付 DataSet + TableAdapter のコードが自動生成されます。

xsd ファイルを開くと、以下のように表示されるはずです。

xsd ファイルの作成

自動生成されたコードは、Web アプリケーションプロジェクトの場合は xsd ファイルの直下に、Web サイトプロジェクトの場合は Temporary ASP.NET Files フォルダ内にあります。

この TableAdapter コードを partial class を使って拡張して、必要なレコードのみ DB から取得するためのクラス/メソッドを実装します。

以下のようになります。GetDataByIndex メソッドの引数名 startRowIndex, maximumRowsは、ObjectDataSource がデフォルトでその名前を参照していますので、そのまま使うのが面倒がないです(変更する場合は MaximumRowsParameterName プロパティと StartRowIndexParameterName プロパティに変更後の引数名を設定してください)。名前空間名、クラス名は、自動生成されたコードを参照してください。

using System;
using System.Data;
using System.Configuration;
using System.Data.SqlClient;
using System.ComponentModel;

namespace ProductsDataSetTableAdapters
{
  public partial class ProductsTableAdapter
  {
    [DataObjectMethod(DataObjectMethodType.Select, true)]
    public ProductsDataSet.ProductsDataTable GetDataByIndex(int startRowIndex, int maximumRows)
    {
      SqlDataAdapter adapter;
      string query = String.Format(
        "SELECT * " +
          "FROM (" + 
             "SELECT *, ROW_NUMBER() OVER (ORDER BY [ProductID] ASC) AS rownum " + 
             "FROM [Products]) AS DerivedTable " +
          "WHERE rownum BETWEEN {0} AND {1} " +
          "ORDER BY [ProductID] ASC",
           startRowIndex + 1, maximumRows + startRowIndex);
      adapter = new SqlDataAdapter(query, this.Connection);

      ProductsDataSet dataset = new ProductsDataSet();
      adapter.Fill(dataset.Products);
      return dataset.Products;
    }

    public int GetNumberOfMessages()
    {
      SqlCommand command;
      command = 
        new SqlCommand("SELECT COUNT(*) FROM [Products]", this.Connection);
      this.Connection.Open();
      int rows = (int)command.ExecuteScalar();
      this.Connection.Close();
      return rows;
    }
  }
}

最後に、ObjectDataSource と ListView を実装した aspx ページを作成します。コードは以下のようになります。

<%@ 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">

</script>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
  <title></title>
  <style type="text/css">
    table.style1
    {
      border-style: solid;
      border-width: 2px;
      border-color: Black;
      text-align: center;
      border-collapse: collapse;
    }
       
    table.style1 th
    {
      border-style: solid;
      border-width: 2px 1px 2px 1px;
      border-color: Black;
      background-color: #6699FF;
      color: #FFFFFF;
    }
        
    table.style1 td
    {
      border-style: solid;
      border-width: 1px;
      border-color: Black;        
    }
        
    .alternate
    {
      background-color: #CCFFFF;
    }  
  </style>
</head>
<body>
  <form id="form1" runat="server">
  <div>
    <asp:ObjectDataSource ID="ObjectDataSource1" 
      runat="server" 
      SelectMethod="GetDataByIndex" 
      SelectCountMethod="GetNumberOfMessages" 
      EnablePaging="True"             
      TypeName="ProductsDataSetTableAdapters.ProductsTableAdapter">
    </asp:ObjectDataSource>
    <asp:ListView ID="ListView1" 
      runat="server" 
      DataKeyNames="ProductID" 
      DataSourceID="ObjectDataSource1" 
      EnableModelValidation="True">
      <LayoutTemplate>
        <table id="Table1" runat="server" class="style1">
          <tr id="Tr1" runat="server" style="">
            <th id="Th1" rowspan="2" runat="server">ProductID</th>
            <th id="Th2" colspan="7" runat="server">ProductName</th>
            <th id="Th3" rowspan="2" runat="server">Discontinued</th>
          </tr>
          <tr>
            <th id="Th4" runat="server">SupplierID</th>
            <th id="Th5" runat="server">CategoryID</th>
            <th id="Th6" runat="server">QuantityPerUnit</th>
            <th id="Th7" runat="server">UnitPrice</th>
            <th id="Th8" runat="server">UnitsInStock</th>
            <th id="Th9" runat="server">UnitsOnOrder</th>
            <th id="Th10" runat="server">ReorderLevel</th>
          </tr>                                
          <tr ID="itemPlaceholder" runat="server">
          </tr>
        </table>
      </LayoutTemplate>
      <AlternatingItemTemplate>
        <tr class="alternate">
          <td rowspan="2">
            <asp:Label ID="ProductIDLabel" 
              runat="server" 
              Text='<%# Eval("ProductID") %>' />
          </td>
            <td colspan="7">
            <asp:Label ID="ProductNameLabel" 
              runat="server" 
              Text='<%# Eval("ProductName") %>' />
          </td>
          <td rowspan="2">
            <asp:CheckBox ID="DiscontinuedCheckBox" 
              runat="server" 
              Checked='<%# Eval("Discontinued") %>' 
              Enabled="false" />
          </td>
        </tr>
        <tr class="alternate">
          <td>
            <asp:Label ID="SupplierIDLabel" 
              runat="server" 
              Text='<%# Eval("SupplierID") %>' />
          </td>
          <td>
            <asp:Label ID="CategoryIDLabel" 
              runat="server" 
              Text='<%# Eval("CategoryID") %>' />
          </td>
          <td>
            <asp:Label ID="QuantityPerUnitLabel" 
              runat="server" 
              Text='<%# Eval("QuantityPerUnit") %>' />
          </td>
          <td>
            <asp:Label ID="UnitPriceLabel" 
              runat="server" 
              Text='<%# Eval("UnitPrice") %>' />
          </td>
          <td>
            <asp:Label ID="UnitsInStockLabel" 
              runat="server" 
              Text='<%# Eval("UnitsInStock") %>' />
          </td>
          <td>
            <asp:Label ID="UnitsOnOrderLabel" 
              runat="server" 
            Text='<%# Eval("UnitsOnOrder") %>' />
          </td>
            <td>
            <asp:Label ID="ReorderLevelLabel" 
               runat="server" 
               Text='<%# Eval("ReorderLevel") %>' />
          </td>
        </tr>
      </AlternatingItemTemplate>
      <ItemTemplate>
        <tr>
          <td rowspan="2">
            <asp:Label ID="ProductIDLabel" 
              runat="server" 
              Text='<%# Eval("ProductID") %>' />
          </td>
          <td colspan="7">
          <asp:Label ID="ProductNameLabel" 
            runat="server" 
            Text='<%# Eval("ProductName") %>' />
          </td>
            <td rowspan="2">
              <asp:CheckBox ID="DiscontinuedCheckBox" 
                runat="server" 
                Checked='<%# Eval("Discontinued") %>' 
                Enabled="false" />
            </td>
        </tr>
        <tr>
         <td>
           <asp:Label ID="Label1" 
             runat="server" 
             Text='<%# Eval("SupplierID") %>' />
         </td>
         <td>
           <asp:Label ID="Label2" 
             runat="server" 
             Text='<%# Eval("CategoryID") %>' />
         </td>
         <td>
           <asp:Label ID="Label3" 
             runat="server" 
             Text='<%# Eval("QuantityPerUnit") %>' />
         </td>
         <td>
           <asp:Label ID="Label4" 
             runat="server" 
             Text='<%# Eval("UnitPrice") %>' />
         </td>
         <td>
           <asp:Label ID="Label5" 
             runat="server" 
             Text='<%# Eval("UnitsInStock") %>' />
         </td>
         <td>
           <asp:Label ID="Label6" 
             runat="server" 
             Text='<%# Eval("UnitsOnOrder") %>' />
         </td>
         <td>
           <asp:Label ID="Label7" runat="server" 
              Text='<%# Eval("ReorderLevel") %>' />
         </td>
       <tr>
      </ItemTemplate>
    </asp:ListView>
    <asp:DataPager ID="DataPager1" 
      runat="server" 
      PageSize="7" 
      PagedControlID="ListView1">
      <Fields>
        <asp:NextPreviousPagerField 
          ButtonType="Link" 
          ShowFirstPageButton="True" 
          ShowNextPageButton="False" 
          ShowPreviousPageButton="False" 
          FirstPageText="&lt;&lt;最初" />
        <asp:NumericPagerField 
          ButtonCount="5"
          PreviousPageText="&lt;前の 5 ページ"
          NextPageText="次の 5 ページ&gt;"/>
        <asp:NextPreviousPagerField 
          ButtonType="Link" 
          ShowLastPageButton="True" 
          ShowNextPageButton="False" 
          ShowPreviousPageButton="False" 
          LastPageText="最後&gt;&gt;" />
      </Fields>
    </asp:DataPager>
  </div>
  </form>
</body>
</html>

先の記事の方法と今回の記事の方法とで、どちらが簡単かと言えば、正直言ってどっちもどっちって感じです。

Tags: , ,

Paging

カスタムページャー

by WebSurfer 25. August 2010 22:42

ASP.NET 2.0 で利用できるデータソースコントロール(SqlDataSource など)とデータバインドコントロール(GridView など)を用いると、ほとんどコードを自力で書くことなくページング機能を実装できます。

ところが、GridView は意外と融通性がなく、例えば 1 レコードを複数行に表示する場合は実質的に使えません(使って使えないことはないですが、問題が多いです)。

ASP.NET 3.5 が使えなかった時代は、Repeater を使うという選択になったのですが、ページングが必要な場合は自分でコードを書いて実装する必要があります。その例を書いてみました。

実行結果は以下のようになります(縮小してあります)。

Repeater を使ったページング

ASP.NET 3.5 の ListView を使えばこのような苦労はないので、今となってはこの例が役に立つことはないかもしれませんけど。

実装しなければならないのは以下のとおりです。

  • ページャー(ページングのためのユーザーインターフェイス用カスタムコントロール)
  • ページング制御しながらデータを抽出するストアドプロシージャ
  • ユーザーによるページャーの操作に応じて、ストアドプロシージャを利用して DataTable を作成し Reapter にバインドするプログラムを含む aspx ファイル。

それぞれについてコードを記載します。説明はコードの中のコメントを参照してください。

ページャー
using System;
using System.Web.UI;
using System.Web.UI.WebControls;

// 以下のようなページャーが表示される。
//
// <<最初 <前へ 1, 2, 3, 4, 5 次へ> 最後>>
//
// クリックするとポストバックがかかり、そのクリックした
// ページが表示されるようコントロールする。

namespace CustomWebFormsControls
{
  public class PageNumberer : WebControl, IPostBackEventHandler
  {
    private int _selectedPage, _count, _displayedPages;

    // 現在選択されているページ番号
    public int SelectedPage
    {
      get
      {
        if (_selectedPage == 0)
        {
          object obj = ViewState["SelectedPage"];
          _selectedPage = (obj != null) ? (int)obj : 1;
        }
        return _selectedPage;
      }
      set
      {
        ViewState["SelectedPage"] = value;
        _selectedPage = value;
      }
    }

    // ページ総数
    public int Count
    {
      get
      {
        if (_count == 0)
        {
          object obj = ViewState["Count"];
          _count = (obj != null) ? (int)obj : 1;
        }
        return _count;
      }
      set
      {
        ViewState["Count"] = value;
        _count = value;
      }
    }

    // ページャーに表示するページの最大数
    // 例えば、DisplayedPages="7" と設定すると、Count が
    // 8 ページ以上ある場合、以下のように表示される。
    // 1, 2, 3, 4, 5, 6, 7 次へ> 最後 >>
    public int DisplayedPages
    {
      get
      {
        if (_displayedPages == 0)
        {
          object obj = ViewState["DisplayedPages"];
          _displayedPages = (obj != null) ? (int)obj : 1;
        }
        return _displayedPages;
      }
      set
      {
        ViewState["DisplayedPages"] = value;
        _displayedPages = value;
      }
    }

    // html の一番外側は div 要素。
    protected override HtmlTextWriterTag TagKey
    {
      get
      {
        return HtmlTextWriterTag.Div;
      }
    }

    protected override void RenderContents(HtmlTextWriter writer)
    {
      int startPage;  // 左端に表示するページ番号
      int endPage;    // 右端に表示するページ番号

      if (Count > DisplayedPages)
      {
        // SelectedPage の前後のページの数を求める。
        // 例えば、
        //        1, 2, 3, 4, 5, 6, 7 次へ> 最後 >>
        // で 2 が SelectedPage の場合、prevCount = 1,
        // nextCount = 5 となる。
        int prevCount = Math.Abs((DisplayedPages - 1) / 2);

        if (SelectedPage <= prevCount)
        {
          prevCount = SelectedPage - 1;
        }

        int nextCount = DisplayedPages - prevCount - 1;

        if (SelectedPage + nextCount > Count)
        {
          nextCount = Count - SelectedPage;
          prevCount = DisplayedPages - nextCount - 1;
        }

        // 上で求めた prevCount, nextCount を基に
        // startPage, endPage を計算する。
        startPage = SelectedPage - prevCount;
        endPage = SelectedPage + nextCount;
      }
      else
      {
        startPage = 1;
        endPage = Count;
      }

      if (startPage > 1)
      {
        RenderItem(writer, "&lt;&lt;最初", 1);
      }

      if (SelectedPage > 1)
      {
        RenderItem(writer, "&lt;前へ", SelectedPage - 1);
      }

      for (int i = startPage; i <= endPage; i++)
      {
        string label;
        if (i != endPage)
        {
          label = i.ToString() + ",";
        }
        else
        {
          label = i.ToString();
        }

        if (i == SelectedPage)
        {
          RenderItem(writer, label, 0);
        }
        else
        {
          RenderItem(writer, label, i);
        }
      }

      if (SelectedPage < Count)
      {
        RenderItem(writer, "次へ&gt;", SelectedPage + 1);
      }

      if (endPage < Count)
      {
        RenderItem(writer, "最後&gt;&gt;", Count);
      }
    }

    void RenderItem(HtmlTextWriter writer, string text, int pageNum)
    {
      // <span>
      writer.RenderBeginTag(HtmlTextWriterTag.Span);

      // <a href="javascript:__doPostBack('ユニークID','ページ番号')">
      if (pageNum != 0)
      {
        writer.AddAttribute(
          HtmlTextWriterAttribute.Href,
          Page.ClientScript.GetPostBackClientHyperlink(
            this, pageNum.ToString())
        );
        writer.RenderBeginTag(HtmlTextWriterTag.A);
      }

      // ページ番号
      writer.Write(text);

      // </a>
      if (pageNum != 0)
      {
        writer.RenderEndTag();
      }

      // </span>
      writer.RenderEndTag();
    }

    private static readonly object EventSelectedPageChanged = null;

    // これは += と -= の定義。
    public event EventHandler SelectedPageChanged
    {
      add
      {
        Events.AddHandler(EventSelectedPageChanged, value);
      }
      remove
      {
        Events.RemoveHandler(EventSelectedPageChanged, value);
      }
    }

    // サーバーにポストバックされたとき、ページがこの
    // メソッドを呼び出して、__doPostBack() の第 2 引
    // 数(クリックされたページ番号)を eventArgument
    // に渡す。
    void IPostBackEventHandler.RaisePostBackEvent(string eventArgument)
    {
      int newPage;
      if (int.TryParse(eventArgument, out newPage))
      {
        this.SelectedPage = newPage;
        OnSelectedPageChanged(EventArgs.Empty);
      }
    }

    protected virtual void OnSelectedPageChanged(EventArgs e)
    {
      EventHandler changehandler =
        (EventHandler)Events[EventSelectedPageChanged];
      if (changehandler != null)
      {
        changehandler(this, e);
      }
    }
  }
}
ストアドプロシージャ

Microsoft が提供しているサンプルデータベース Northwind の Products テーブルを利用しています。

ALTER PROCEDURE dbo.PagedProductList4
(
  @pageNum int = 1,
  @pageSize int = 10,
  @pageCount int OUTPUT
)
/* pageNum: 現在選択されているページ番号
   pageSize: ページ当りの行数 
   @rows: スキップする行数 */
AS
  declare @rows int
  declare @rowCount float

  SET @rows = (@pageNum - 1) * @pageSize
    
SELECT @rowCount = COUNT(*) FROM [Products]

SELECT * 
FROM (
  SELECT *, ROW_NUMBER() 
    OVER (ORDER BY [ProductID] ASC) AS rownum 
    FROM [Products]
    ) AS DerivedTable 
WHERE rownum BETWEEN (@rows + 1) AND (@rows + @pageSize) 
ORDER BY [ProductID] ASC
       
SET @pageCount = CEILING(@rowCount / @pageSize)
aspx ファイル
<%@ Page Language="C#" %>
<%@ Register TagPrefix="MyControl" Namespace="CustomWebFormsControls" %>
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.SqlClient" %>
<%@ Import Namespace="System.Configuration" %>

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

<script runat="server">
  // ついでに、SqlDataSorce, ObjectDataSource は使わな
  // いことで考えました。
  DataTable CreateDataSource(int pageNum, int pageSize)
  {
    string connString = 
      ConfigurationManager.ConnectionStrings["Northwind"].ConnectionString;
    using (SqlConnection sqlConn = new SqlConnection(connString))
    {
      SqlCommand sqlCom = 
        new SqlCommand("dbo.PagedProductList4", sqlConn);
      sqlCom.CommandType = CommandType.StoredProcedure;
      sqlCom.Parameters.AddWithValue("@pageNum", pageNum);
      sqlCom.Parameters.AddWithValue("@pageSize", pageSize);
      SqlParameter param = 
        new SqlParameter("@pageCount", SqlDbType.Int);
      param.Direction = ParameterDirection.Output;
      sqlCom.Parameters.Add(param);

      SqlDataAdapter adapter = new SqlDataAdapter();
      adapter.SelectCommand = sqlCom;

      DataSet ds = new DataSet();
      adapter.Fill(ds);

      pn1.Count = (int)param.Value;
      pn2.Count = (int)param.Value;

      return ds.Tables[0];
    }
  }
    
  // ページ当りの行数
  protected int pageSize = 7;
    
  void Page_Load(Object sender, EventArgs e)
  {
    if (!IsPostBack)
    {
      Repeater1.DataSource = 
        CreateDataSource(pn1.SelectedPage, pageSize);
      Repeater1.DataBind();
    }
  }

  protected void pn1_SelectedPageChanged(object sender, EventArgs e)
  {
    Repeater1.DataSource = 
      CreateDataSource(pn1.SelectedPage, pageSize);
    Repeater1.DataBind();
    pn2.SelectedPage = pn1.SelectedPage;
  }

  protected void pn2_SelectedPageChanged(object sender, EventArgs e)
  {
    Repeater1.DataSource = 
      CreateDataSource(pn2.SelectedPage, pageSize);
    Repeater1.DataBind();
    pn1.SelectedPage = pn2.SelectedPage;
  }
</script>

<html>
<head>
<title>無題のページ</title>
  <style type="text/css">
    table.style1
    {
      border-style: solid;
      border-width: 2px;
      border-color: Black;
      text-align: center;
      border-collapse: collapse;
    }
       
    table.style1 th
    {
      border-style: solid;
      border-width: 2px 1px 2px 1px;
      border-color: Black;
      background-color: #6699FF;
      color: #FFFFFF;
    }
        
    table.style1 td
    {
      border-style: solid;
      border-width: 1px;
      border-color: Black;        
    }
        
    .alternate
    {
      background-color: #CCFFFF;
    }
        
    .PageNumbers
    {
      display:inline;
    }

    .PageNumbers span
    {
      padding-left: 10px;
    }        
  </style>
</head>
<body>
  <form id="form1" runat="server">
  <div>
    <MyControl:PageNumberer ID="pn1" 
      runat="server" 
      DisplayedPages="5" 
      onselectedpagechanged="pn1_SelectedPageChanged" 
      CssClass="PageNumbers"/>
    <asp:Repeater ID="Repeater1" runat="server">
      <HeaderTemplate>
        <table class="style1">
          <tr>
            <th rowspan="2">ProductID</th>
            <th colspan="7">ProductName</td>
            <th rowspan="2">Discontinued</th>
          </tr>
          <tr>
            <th>SupplierID</th>
            <th>CategoryID</th>
            <th>QuantityPerUnit</th>
            <th>UnitPrice</th>
            <th>UnitsInStock</th>
            <th>UnitsOnOrder</th>
            <th>ReorderLevel</th>
          </tr>
      </HeaderTemplate>

      <ItemTemplate>
          <tr>
            <td rowspan="2"><%# Eval("ProductID")%></td>
            <td colspan="7"><%# Eval("ProductName")%></td>
            <td rowspan="2">
              <asp:CheckBox ID="CheckBox1" 
                runat="server" 
                Enabled="False" 
                Checked='<%# Eval("Discontinued") %>' />
            </td>
          </tr>
          <tr>
            <td><%# Eval("SupplierID")%></td>
            <td><%# Eval("CategoryID")%></td>
            <td><%# Eval("QuantityPerUnit")%></td>
            <td><%# Eval("UnitPrice")%></td>
            <td><%# Eval("UnitsInStock")%></td>
            <td><%# Eval("UnitsOnOrder")%></td>
            <td><%# Eval("ReorderLevel")%></td>
          </tr>
      </ItemTemplate>
            
      <AlternatingItemTemplate>
          <tr class="alternate">
            <td rowspan="2"><%# Eval("ProductID")%></td>
            <td colspan="7"><%# Eval("ProductName")%></td>
            <td rowspan="2">
              <asp:CheckBox ID="CheckBox1" 
                runat="server" 
                Enabled="False" 
                Checked='<%# Eval("Discontinued") %>' />
            </td>
          </tr>
          <tr class="alternate">
            <td><%# Eval("SupplierID")%></td>
            <td><%# Eval("CategoryID")%></td>
            <td><%# Eval("QuantityPerUnit")%></td>
            <td><%# Eval("UnitPrice")%></td>
            <td><%# Eval("UnitsInStock")%></td>
            <td><%# Eval("UnitsOnOrder")%></td>
            <td><%# Eval("ReorderLevel")%></td>
          </tr>
      </AlternatingItemTemplate>
      <FooterTemplate>
        </table>
      </FooterTemplate>
    </asp:Repeater>
    <MyControl:PageNumberer ID="pn2" 
      runat="server" 
      DisplayedPages="5" 
      onselectedpagechanged="pn2_SelectedPageChanged" 
      CssClass="PageNumbers"/>
  </div>
  </form>
</body>
</html>

Tags: ,

Paging

About this blog

2010年5月にこのブログを立ち上げました。その後 ブログ2 を追加し、ここは ASP.NET 関係のトピックス、ブログ2はそれ以外のトピックスに分けました。

Calendar

<<  November 2019  >>
MoTuWeThFrSaSu
28293031123
45678910
11121314151617
18192021222324
2526272829301
2345678

View posts in large calendar