用存储过程实现GridView分页,PageSize是50,运行时第一页显示第1-50条数据;但是第二页却显示第101-150条数据,第三页显示201-250 ……也就是说有一半的数据不见了。
以下是存储过程:
CREATE PROCEDURE [dbo].[GetP]
    @PageIndex INT,
    @PageSize  INT,
    @RecordCount INT OUT,
    @PageCount INT OUT
AS 
/*获取记录数*/
SELECT @RecordCount = COUNT(*) FROM Products
/*计算页面数据*/
SET @PageCount = CEILING(@RecordCount * 1.0 / @PageSize)
/* 基于SQL SERVER 2005 */
SELECT SerialNumber,ProductID,ProductName FROM
(SELECT ProductID,ProductName,ROW_NUMBER() OVER (ORDER BY ProductID ASC) AS SerialNumber FROM Products ) AS T
WHERE T.SerialNumber > (@PageIndex * @PageSize)
--  and T.SerialNumber <= ((@PageIndex+1) * @PageSize)注:“and T.SerialNumber <= ((@PageIndex+1) * @PageSize)”这句如果不注释掉可以正确显示数据,但是下面的分页没了,不知道有什么办法?以下是GridView1_OnPageIndexChanging的代码:
public void GridView1_OnPageIndexChanging(object sender, GridViewPageEventArgs e)
    {       
        SqlDataAdapter adapter = new SqlDataAdapter("GetP", con);
        DataSet ds = new DataSet();
        adapter.SelectCommand.CommandType = CommandType.StoredProcedure;
        adapter.SelectCommand.Parameters.Add("@PageIndex", SqlDbType.Int, 4).Value = e.NewPageIndex;
        adapter.SelectCommand.Parameters.Add("@PageSize", SqlDbType.Int, 4).Value = GridView1.PageSize;
        adapter.SelectCommand.Parameters.Add("@RecordCount", SqlDbType.Int, 4);
        adapter.SelectCommand.Parameters.Add("@PageCount", SqlDbType.Int, 4);
        adapter.SelectCommand.Parameters["@RecordCount"].Direction = ParameterDirection.Output;
        adapter.SelectCommand.Parameters["@PageCount"].Direction = ParameterDirection.Output;        this.GridView1.PageIndex = e.NewPageIndex;
        adapter.Fill(ds, "p");
        GridView1.DataSource = ds.Tables["p"].DefaultView;
        GridView1.DataBind();
        TextBox2.Text = adapter.SelectCommand.Parameters["@RecordCount"].Value.ToString();
        TextBox3.Text = adapter.SelectCommand.Parameters["@PageCount"].Value.ToString();
    }请问是哪里的错误?谢谢!

解决方案 »

  1.   

    不多说了. 代码如下.
      GridView控件中的"选择"操作纯粹是一个UI概念,它的SelectedIndex属性与表格的可视数据行中的当前被选中的行的索引相对应。如果你启用了表格的分页和排序功能,在执行分页或排序操作之后,SelectedIndex的值仍然不会变化,因此在执行这些操作之后,一个新数据行被选中了。在某些环境下,保留对指定数据行的选中更好,即使该行在表格的当前页面中并不可视。下面的例子演示了如何在排序和分页操作之后仍然保留当前选中的数据行。Sub GridView1_DataBound(ByVal sender As Object, ByVal e As System.EventArgs)
     Dim Row As GridViewRow
     Dim SelectedValue As String = ViewState("SelectedValue")
     If SelectedValue Is Nothing Then
      Return
     End If 
     ' 检测选择的行是哪个并重新选中它
     For Each Row In GridView1.Rows
      Dim KeyValue As String = GridView1.DataKeys(Row.RowIndex).Value
      If (KeyValue = SelectedValue) Then
       GridView1.SelectedIndex = Row.RowIndex
      End If
     Next
    End SubProtected Sub GridView1_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs)
     ' 保存选中行的索引
     If (Not GridView1.SelectedIndex = -1) Then
      ViewState("SelectedValue") = GridView1.SelectedValue
     End If
    End SubProtected Sub GridView1_PageIndexChanging(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewPageEventArgs)
     ' 重置选中索引
     GridView1.SelectedIndex = -1
    End SubSub GridView1_Sorting(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewSortEventArgs)
     ' 重置选择索引
     GridView1.SelectedIndex = -1
    End Sub   GridView和DetailsView还支持一种用于分页和排序的特殊模式,它利用客户端向服务器的回调(callback)操作来获取新页面的数据或最近排序过的数据。要激活这个特性,必须把EnableSortingAndPagingCallbacks属性设置为真。请注意,当我们执行分页或排序操作的时候,页面不需要发回(postback)以检索新值(尽管执行了客户端脚本向服务器的回调操作)。当GridView或DetailsView包含模板字段的时候是不支持这个特性的。当这个特性被激活的时候,不支持在CommandField(命令字段)中显示"选择"按钮。<asp:GridView AllowPaging="True" AllowSorting="True" AutoGenerateColumns="False" DataKeyNames="au_id" DataSourceID="SqlDataSource1" EnableSortingAndPagingCallbacks="True" ID="GridView1" runat="server">
    ……
    </asp:GridView>   尽管GridView、DetailsView和FormView为分页器(pager)UI提供了默认的显示方式,你仍然可以通过设置PagerTemplate属性来自定义分页器的显示。在这个模板中,你可以放置按钮控件,并把它的CommandName属性设置为Page,把它的属性设置为First、Prev、Next、Last或<number>,其中<number>是特定页面的索引值。下面的例子演示了GridView和DetailsView控件定义的PagerTemplate。<PagerTemplate>
    <asp:LinkButton CommandName="Page" CommandArgument="First" ID="LinkButton1" runat="server" Style="color: white">&lt;&lt; First</asp:LinkButton>
    <asp:LinkButton CommandName="Page" CommandArgument="Prev" ID="LinkButton2" runat="server" Style="color: white">&lt; Prev</asp:LinkButton>
    [Records <%= GridView1.PageIndex * GridView1.PageSize %> - <%= GridView1.PageIndex * GridView1.PageSize + GridView1.PageSize - 1 %>]
    <asp:LinkButton CommandName="Page" CommandArgument="Next" ID="LinkButton3" runat="server" Style="color: white">Next &gt;</asp:LinkButton>
    <asp:LinkButton CommandName="Page" CommandArgument="Last" ID="LinkButton4" runat="server" Style="color: white">Last &gt;&gt;</asp:LinkButton> 
    </PagerTemplate> 
      

  2.   

    a... 不好意思, 拉错了...
    前台代码如下:
    <TABLE id="Table1" style="Z-INDEX: 101; LEFT: 32px; WIDTH: 752px; POSITION: absolute; TOP: 16px; HEIGHT: 312px" cellSpacing="0" cellPadding="0" width="752" border="0">
    <TR>
                  <TD style="HEIGHT: 29px"><FONT face="宋体">DataList分页技术和超级链接</FONT></TD>
    </TR>
    <TR>
               <TD style="HEIGHT: 252px"><asp:datalist id="DataList1" runat="server" Width="576px" Height="96px">
                                                     <HeaderTemplate>
                                                            定单编号<td>
                                                            员工编号<td>
                                                            定单日期<td>
                                                            运费<td>
                                                            运往所在城市
                                                     </HeaderTemplate>
                                                     <ItemTemplate>
    <%# show(DataBinder.Eval(Container.DataItem,"OrderID"))%>
    <td><%# DataBinder.Eval(Container.DataItem, "NAME") %></td>
                                                            <td><%# DataBinder.Eval(Container.DataItem,"CustomerID")%>
                                                            <td><%# DataBinder.Eval(Container.DataItem,"OrderDate")%>
                                                            <td>
    <%# DataBinder.Eval(Container.DataItem,"Freight")%>
                                                            <td><%# DataBinder.Eval(Container.DataItem,"ShipCity")%>
                                                     </ItemTemplate>
                                              </asp:datalist></TD>
                                </TR>
                                <TR>
                                       <TD><FONT face="宋体"><asp:linkbutton id="FirstLB" runat="server" OnCommand="LinkButton_Click" CommandName="first">第一页</asp:linkbutton>&nbsp;
    <asp:linkbutton id="PreviousLB" runat="server" OnCommand="LinkButton_Click" CommandName="prev">上一页</asp:linkbutton>&nbsp;<asp:linkbutton id="NextLB" runat="server" OnCommand=LinkButton_Click 
    CommandName="next">下一页</asp:linkbutton>&nbsp;<asp:linkbutton id="EndLB" runat="server" OnCommand=LinkButton_Click 
    CommandName="end">最后一页</asp:linkbutton>&nbsp;&nbsp;总<asp:label id="TotalLbl" runat="server"></asp:label>页 当前第<asp:label id="CurrentLbl" runat="server"></asp:label>页
    <asp:linkbutton id="JumpLB" runat="server" OnCommand=LinkButton_Click CommandName="jump">跳到</asp:linkbutton>第
           <asp:textbox id="TextBox1" runat="server" Width="90px"></asp:textbox>
    页</FONT></TD>
                                </TR>
    </TABLE>
      

  3.   

    后台代码如下:private void Page_Load(object sender, System.EventArgs e)
            {
                // 在此处放置用户代码以初始化页面
                PageSize = 12;//每页12条记录 
                if(!Page.IsPostBack)
                {
                    this.DataListBind();
                    CurrentPage = 0;//当前页习惯设为0
                    ViewState["PageIndex"] = 0;//页索引也设为0 
                    //计算总共有多少记录
                    RecordCount = CalculateRecord(); 
                    //计算总共有多少页
                    PageCount = RecordCount/PageSize;
                    this.TotalLbl.Text = PageCount.ToString();//显示总页数
                    ViewState["PageCount"] = PageCount;//会话session 对整个 application 有效 ,而视图状态 viewstate相当于某个页面的 session 
                }
            }
            
        
        
            
            //计算总共有多少条记录
            private  int CalculateRecord()
            {
                try
                {
                    int recordCount;
                    SqlConnection con=new SqlConnection("server=.;database=Northwind;uid=sa;pwd=");//数据库使用Northwind;
                    con.Open();
                    string sql= "select count(*) as count from Orders";
                    SqlCommand cmd = new SqlCommand(sql,con);
                    SqlDataReader sdr = cmd.ExecuteReader();
                    if(sdr.Read())
                    {
                        recordCount = Int32.Parse(sdr["count"].ToString());
                    }
                    else
                    {
                        recordCount = 0;
                    }
                    sdr.Close();
                    con.Close();
                    return recordCount;
                }
                catch(Exception ex)
                {
                    throw new Exception(ex.Message);
                }
            }
            //以第一列定单号做个超级链接,链接到第二页显示定单详细信息
            public string show (object orderID)
            {
             return "<a href=WebForm2.aspx?id="+orderID+" target='_blank'>"+orderID+" </a>";
            }
            //将数据绑定到Datalist控件
            public void DataListBind()
            {
                try
                {
                    
                    int StartIndex = CurrentPage*PageSize;//设定导入的起终地址
                    string sql = "select * from Orders";
                    DataSet ds = new DataSet();
                    SqlConnection con=new SqlConnection("server=.;database=Northwind;uid=sa;pwd=");
                    con.Open();
                    SqlDataAdapter sda= new SqlDataAdapter(sql,con);
                    
                    sda.Fill(ds,StartIndex,PageSize,"orders");//这是sda.Fill方法的第一次重载,里面的变量分别是数据集DataSet ,开始记录数StartRecord,最大的记录数MaxRecord,数据表名TableName
                    this.DataList1.DataSource = ds.Tables["orders"].DefaultView;
                    this.DataList1.DataBind();
                    this.PreviousLB.Enabled = true;
                    this.NextLB.Enabled = true;
                    if(CurrentPage==(PageCount-1)) this.NextLB.Enabled = false;//当为最后一页时,下一页链接按钮不可用
                    if(CurrentPage==0) this.PreviousLB.Enabled = false;//当为第一页时,上一页按钮不可用
                    this.CurrentLbl.Text = (CurrentPage+1).ToString();//当前页数
                }
                catch(Exception ex)
                {
                    throw new Exception(ex.Message);
                } 
            } 
            public void LinkButton_Click(Object sender,CommandEventArgs e)//自己编写的按钮点击事件
            {
                CurrentPage = (int)ViewState["PageIndex"];//获得当前页索引
                PageCount = (int)ViewState["PageCount"];//获得总页数 
                string cmd = e.CommandName;
                //判断cmd,以判定翻页方向
                switch(cmd)
                {
                    case "prev"://上一页
                        if(CurrentPage>0) CurrentPage--;
                        break;
                    case "next":
                        if(CurrentPage<(PageCount-1)) CurrentPage++;//下一页
                        break;
                    case "first"://第一页
                        CurrentPage=0;
                        break;
                    case "end"://最后一页
                        CurrentPage=PageCount-1;
                        break;
                    case "jump"://跳转到第几页
                        if(this.TextBox1.Text.Trim()==""||Int64.Parse(this.TextBox1.Text.Trim())>PageCount)//如果输入数字为空或超出范围则返回
                            return;
                        else
                        {
                            CurrentPage=Int32.Parse(this.TextBox1.Text.ToString())-1;
                            break;
                        } 
                        
                } 
                ViewState["PageIndex"] = CurrentPage;//获得当前页 
                this.DataListBind();//重新将DataList绑定到数据库 
            }
      

  4.   

    zhaochong12(笨鸟),您解答的好象不是我所要解决的问题 :)
    再次求教!
      

  5.   

    SELECT SerialNumber,ProductID,ProductName FROM
    (SELECT ProductID,ProductName,ROW_NUMBER() OVER (ORDER BY ProductID ASC) AS SerialNumber FROM Products ) AS T
    WHERE T.SerialNumber > (@PageIndex * @PageSize)
    and T.SerialNumber <= ((@PageIndex+1) * @PageSize)
    你这里是没有错的......
    没有分页是由于你每一次查询出来的数据都是在50条内....
    当这些数据赋值给GridView
    所以它只有一页..就不会出现下面的分页了..,
    你必须自己控制首页、上一页、下一页、最未页和跳转页....
    而不是GridView自带的上一页、下一页等
      

  6.   

    sinatly(爱在爱你) ,谢谢您的指导。
    "and T.SerialNumber <= ((@PageIndex+1) * @PageSize)"这句我注销掉了,数据赋值给GridView的就不止一页了,但是出来的结果如我前面所说的“第一页显示第1-50条数据;但是第二页却显示第101-150条数据,第三页显示201-250 ……”,其中51-100,151-200……等的数据没有显示。不知道是什么原因?
      

  7.   

    "and T.SerialNumber <= ((@PageIndex+1) * @PageSize)"这句不用注销掉啊
    你用存储过程控制分页的就必须自己控制上一页,下一页等翻页的操作.以及显示当前页和总页数等...
      

  8.   

    意思是说,你按上一页的操作中计算当前页,总页数必须自己去控制..
    而不是利用 GridView本身的上一页下一页所提供的操作...