波斯马BOSSMA Information Technology

GridView通用分页模型

发布时间:2010年11月18日 / 分类:ASP.NET / 14,966 次浏览 / 评论

GridView的本身支持分页,一般情况下我们可以通过如下几个步骤实现分页:

1、更改GrdView控件的AllowPaging属性为true;

2、更改GrdView控件的PageSize属性为一个数值(默认为10);

3、更改GrdView控件的PageSetting属性;

4、为GridView添加事件:OnPageIndexChanging

大多数情况下通过上边的步骤就可以实现GridView的分页了,当然很多代码需要你自己来写。

但是有时候我们需要自定义分页模板,还希望能通过更统一以及更少的代码来实现这个分页功能。考虑到这些问题,我实现了一个通用的GridView分页模型,发布出来,仅供大家参考。

这个分页模型在使用自定义数据进行分页时是有问题的,即通过设置记录总数,每次只绑定当前分页数据到GridView的分页方式。我新写了一篇文章来解决这个问题,需要的朋友请阅读:GridView自定义分页的实现方式

点击这里下载示例程序 (例子是最近(20110927)写的,和文中有些出入,请以实际代码为准)

1、创建一个基础页面类

BasePage,继承System.Web.UI.Page

在这个基类中,创建几个通用的分页属性和方法,然后需要分页的页面都继承这个基类。

public class BasePage : System.Web.UI.Page
{
??? public BasePage()
??? {
??? }

??? #region 分页相关属性和方法
??? /// <summary>
??? /// 总的记录数,目前仅用于自定义记录数
??? /// </summary>
??? protected int GridView_RecordCount = 0;

??? /// <summary>
??? /// 使用自定义的记录数
??? /// 需要设置GridView_RecordCount
??? /// 如果一次性绑定全部数据,不需要使用自定义,GridView可以通过DataSource自己获取
??? /// </summary>
??? protected bool IsUseCustomRecordCount = false;

??? /// <summary>
??? /// 实现GridView数据绑定的虚方法
??? /// 在具体的页面类中重写这个方法,在PageTurn方法中就会调用重写的方法,以实现分页后的数据重新绑定
??? /// </summary>
??? protected virtual void GridView_DataBind()
??? {
??? }

??? /// <summary>
??? /// 分页页码跳转
??? /// </summary>
??? /// <param name="sender">跳转按钮</param>
??? /// <param name="e"></param>
??? protected void GridView_PageTurn(object sender, EventArgs e)
??? {
??????? System.Web.UI.WebControls.Button btnGoPage;
??????? System.Web.UI.WebControls.GridView GridView1;
??????? System.Web.UI.WebControls.TextBox txtGoPage;
??????? try
??????? {
??????????? btnGoPage = (System.Web.UI.WebControls.Button)sender;
??????????? GridView1 = (System.Web.UI.WebControls.GridView)btnGoPage.NamingContainer.Parent.Parent;
??????????? txtGoPage = (System.Web.UI.WebControls.TextBox)GridView1.BottomPagerRow.FindControl("txtGoPage");
??????? }
??????? catch
??????? {
??????????? MessageBox.Show(this.Page, "页码输入框和跳转按钮都必须在GridView的分页模板中!");
??????????? return;
??????? }

??????? int pageIndex = 1;
??????? bool goSuccess = false;

??????? if (!string.IsNullOrEmpty(txtGoPage.Text.Trim()))
??????? {
??????????? if (int.TryParse(txtGoPage.Text.Trim(), out pageIndex))
??????????? {
??????????????? pageIndex--;

??????????????? if (pageIndex >= 0 && pageIndex < GridView1.PageCount)
??????????????? {
??????????????????? goSuccess = true;

??????????????????? GridView1.PageIndex = pageIndex;
??????????????????? GridView_DataBind();
??????????????? }
??????????? }
??????? }

??????? if (!goSuccess)
??????? {
??????????? MessageBox.Show(this.Page, "无效的页码!");
??????????? return;
??????? }
??? }

??? /// <summary>
??? /// 页码改变时触发
??? /// </summary>
??? /// <param name="sender"></param>
??? /// <param name="e"></param>
??? protected void GridView_PageIndexChanging(object sender, System.Web.UI.WebControls.GridViewPageEventArgs e)
??? {
??????? System.Web.UI.WebControls.GridView GridView1 = sender as System.Web.UI.WebControls.GridView;

??????? GridView1.PageIndex = e.NewPageIndex;
??????? GridView_DataBind();
??? }

??? /// <summary>
??? /// GridView数据绑定完毕之后触发,显示记录数
??? /// </summary>
??? /// <param name="sender"></param>
??? /// <param name="e"></param>
??? protected void GridView_DataBound(object sender, EventArgs e)
??? {
??????? //获取当前GridView
??????? System.Web.UI.WebControls.GridView GridView1 = sender as System.Web.UI.WebControls.GridView;

??????? if (GridView1.BottomPagerRow == null)
??????? {
??????????? return;
??????? }

??????? //总是显示分页行
??????? GridView1.BottomPagerRow.Visible = true;

??????? System.Web.UI.WebControls.Label lblRecorCount = (System.Web.UI.WebControls.Label)GridView1.BottomPagerRow.FindControl("lblRecorCount");
??????? if (IsUseCustomRecordCount)
??????? {
??????????? lblRecorCount.Text = GridView_RecordCount.ToString();
??????? }
??????? else
??????? {
??????????? if (GridView1.DataSource == null)
??????????? {
??????????????? return;
??????????? }

??????????? //根据数据类型,动态获取绑定的数据源的记录数
??????????? if (GridView1.DataSource.GetType() == typeof(DataView))
??????????? {
??????????????? lblRecorCount.Text = ((DataView)GridView1.DataSource).Count.ToString();
??????????? }
??????????? else if (GridView1.DataSource.GetType() == typeof(DataTable))
??????????? {
??????????????? lblRecorCount.Text = ((DataTable)GridView1.DataSource).Rows.Count.ToString();
??????????? }
??????????? else if (GridView1.DataSource.GetType() == typeof(DataSet))
??????????? {
??????????????? lblRecorCount.Text = ((DataSet)GridView1.DataSource).Tables[0].Rows.Count.ToString();
??????????? }
??????????? else if (GridView1.DataSource is Array)
??????????? {
??????????????? lblRecorCount.Text = ((Array)GridView1.DataSource).Length.ToString();
??????????? }
??????????? else if (GridView1.DataSource.GetType() is System.Collections.IList)
??????????? {
??????????????? lblRecorCount.Text = ((System.Collections.IList)GridView1.DataSource).Count.ToString();
??????????? }
??????????? else if (GridView1.DataSource.GetType() is System.Collections.ICollection)
??????????? {
??????????????? lblRecorCount.Text = ((System.Collections.ICollection)GridView1.DataSource).Count.ToString();
??????????? }
??????????? else
??????????? {
??????????????? OALog.Write("绑定到GridView的数据类型未知:" + GridView1.DataSource.GetType());
??????????? }
??????? }
??? }
??? #endregion
}

?

2、页面cs文件继承基类:BasePage

public partial class NewsList: BasePage

?

3、在页面添加一个GridView并设置相关属性

?<asp:GridView ID="GridView1" BorderStyle="Solid" BorderWidth="1px" BorderColor="#73B7EA"
??????????????????? Width="100%" runat="server" AutoGenerateColumns="False" HorizontalAlign="Center"
??????????????????? BackColor="White" CellPadding="4" GridLines="None"?? OnPageIndexChanging="GridView_PageIndexChanging" PageSize="10"
??????????????????? AllowPaging="true" OnDataBound="GridView_DataBound">

<Columns>...</Columns>

?<PagerTemplate>
??????????????????????? <div style="text-align: center;"><span style="color: Blue">
??????????????????????????? 共有<asp:label id="lblRecorCount" runat="server"></asp:label>条记录&nbsp;
??????????????????????????? 第<asp:Label ID="lblcurPage" ForeColor="Blue" runat="server" Text='<%# ((GridView)Container.Parent.Parent).PageIndex+1? %>'></asp:Label>页/共<asp:Label ID="lblPageCount" ForeColor="blue" runat="server" Text='<%# ((GridView)Container.Parent.Parent).PageCount %>'></asp:Label>页</span>&nbsp;&nbsp;
??????????????????????????? <asp:LinkButton ID="cmdFirstPage" runat="server" CommandName="Page" CommandArgument="First"? Enabled="<%# ((GridView)Container.Parent.Parent).PageIndex!=0 %>">首页</asp:LinkButton>&nbsp;
??????????????????????????? <asp:LinkButton ID="cmdPreview" runat="server" CommandArgument="Prev" CommandName="Page"? Enabled="<%# ((GridView)Container.Parent.Parent).PageIndex!=0 %>">上一页</asp:LinkButton>&nbsp;
??????????????????????????? <asp:LinkButton ID="cmdNext" runat="server" CommandName="Page" CommandArgument="Next"? Enabled="<%# ((GridView)Container.Parent.Parent).PageIndex!=((GridView)Container.Parent.Parent).PageCount-1 %>">下一页</asp:LinkButton>&nbsp;
??????????????????????????? <asp:LinkButton ID="cmdLastPage" runat="server" CommandArgument="Last" CommandName="Page"? Enabled="<%# ((GridView)Container.Parent.Parent).PageIndex!=((GridView)Container.Parent.Parent).PageCount-1 %>">尾页</asp:LinkButton>&nbsp;&nbsp;
??????????????????????????? 到<asp:TextBox ID="txtGoPage" runat="server" Text='<%# ((GridView)Container.Parent.Parent).PageIndex+1 %>'? Width="30px" CssClass="simpletextbox"></asp:TextBox>页
??????????????????????????? <asp:Button ID="Button3" runat="server" Width="40px"? OnClick="GridView_PageTurn" Text="跳转" CssClass="simplebutton" /></div>
??????????????????? </PagerTemplate>

</asp:GridView>

主要是:

AllowPaging:允许GridView分页

PageSize:默认10

OnDataBound:绑定到基类的事件,用于显示总记录数

OnPageIndexChanging:绑定到基类的事件,用于分页的数据处理

PagerTemplate:包括记录数,当前页,总页数,首页,尾页,上一页,下一页,页码跳转

其中页码跳转事件绑定到基类中的:GridView_PageTurn

?

4、最后编写获取数据的方法

重写基类的GridView_DataBind方法:其中查询数据,然后绑定到GridView。

?protected override void GridView_DataBind()
{

//获取数据,可以是获取全部,也可以是只获取当前页数据

...

//如果你想自己设置总记录数,可以使用IsUseCustomRecordCount

//这种情况适合分页获取少量数据的情况

IsUseCustomRecordCount=true;

GridView_RecordCount=10000;

//绑定数据到GridView

GridView1.DataSource = dv;
GridView1.DataBind();

}

以后只要有需要分页的列表,继承BasePage,然后设置相关属性,编写数据获取代码就可以了。不必在每个页面都编写OnPageIndexChanging,OnDataBound,以及页码跳转的代码,统一实现,节省工作量。

你还可以使用统一的PageSize,只需要在BasePage添加一个属性,然后在GridView中设置PageSize的属性。

以上就是我使用的一个GridView分页模型,欢迎指正!

本博客所有文章如无特别注明均为原创。
复制或转载请以超链接形式注明转自波斯马,原文地址《GridView通用分页模型

关键字:

建议订阅本站,及时阅读最新文章!
【上一篇】 【下一篇】

目前有8 条评论

  1. bossma 0楼:

    @cimba
    去掉前台页面中的 VirtualRecordCount=”0″,这个值每次页面加面加载时,都被设置为0了。这个值不能先设置。

  2. cimba 0楼:

    您好,我就在databind里面这样改:
    VirtualPagerGridView1.PageSize = 10;

    // AllowCacheDatatSource 默认为true,适用于将全部数据一次性绑定到GridView,在分页的过程中数据源不会发生变化。
    // 如果不允许缓存DataSource,则每次页码变化时都调用GridView_DataBind,每次获取数据重新绑定,数据源的实时性更强。
    VirtualPagerGridView1.AllowCacheDatatSource = false;

    // 如果允许自定义分页,则每次获取指定页的数据
    // 同时不能缓存DataSource,即AllowCacheDatatSource=false
    VirtualPagerGridView1.AllowCustomPaging = true;
    VirtualPagerGridView1.VirtualRecordCount = 45;
    运行后,点击“尾页”,就会出现之前提及的错误。
    @bossma

  3. bossma 0楼:

    @cimba
    在我的例子中没有发现你提到的问题,请具体说说场景。这个属性就是自定义分页索引,如果允许自定义分页,就会需要自己设置当前分页索引。在OnPageIndexChanging方法中会调用。

  4. cimba 0楼:

    你好,程序已经下载,谢谢!代码看过有有一个小问题:当使用自定义分页的时候,点击“尾页”会出现错误,错误信息如下:指定的参数已超出有效值的范围。
    参数名: value
    说明: 执行当前 Web 请求期间,出现未处理的异常。请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息。

    异常详细信息: System.ArgumentOutOfRangeException: 指定的参数已超出有效值的范围。
    参数名: value

    源错误:

    行 138: set
    行 139: {
    行 140: base.PageIndex = value;
    行 141: ViewState[“VirtualPageIndex”] = value;
    行 142: }

    源文件: D:\GridViewCustomPage\CustomControl\VirtualPagerGridView.cs 行: 140
    看了半天不大懂,还望您指教:)
    @bossma

  5. bossma 0楼:

    已经发布示例程序,请下载!@cimba

  6. cimba 0楼:

    谢谢!期待你的demo!@bossma

  7. cimba 0楼:

    您这篇文章看了半天,也照了做了,但一直没搞起来,好多处不明白,页面的也可以用messagebox.show 吗?希望能有完整的代码提供学习,或者发我邮箱也行,谢谢!

发表评论