• 分页那些事--追忆学生时代的百思不得解


         临近年关,越多越多的园友开始了对工作、生活的总结,以及对来年目标的确立。这很励志,人是一根能思想的苇草,想来想去,我实在没什么惊天地、泣鬼神的英勇事迹,16年毕业季,按部就班的在时间的马车上颠簸,阅读了几本动物书,赶上大雨,趟着大腿深的积水去公司,一点也不夸张,政府后来还连夜搭铁桥,最后上升到炸湖泄洪,最后雨水终退去。闲言少叙,下面来介绍学时未曾深入理解的分页那些事。

          分页不分真假,技术不论贵贱,存在即合理,只是在特定的时间下特定的情况里发挥着各自的作用,仅此而已。

    1. 代码未动,数据先行。先建立一个Student表,来存储数据(当然也可以使用Code first,这里仅作说明)

    USE [IBCC]
    GO
    
    /****** Object:  Table [dbo].[Student]    Script Date: 2016/12/25 21:09:48 ******/
    SET ANSI_NULLS ON
    GO
    
    SET QUOTED_IDENTIFIER ON
    GO
    
    CREATE TABLE [dbo].[Student](
        [StudentID] [int] NOT NULL,
        [StudentName] [nchar](10) NULL,
        [StudentClass] [nchar](10) NULL,
     CONSTRAINT [PK_Student] PRIMARY KEY CLUSTERED 
    (
        [StudentID] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY]
    
    GO

     2.控件分页,利用GridView控件,手动选择绑定数据源,勾选分页功能,由于非常基础,一键鼠标设置,我这里只贴出效果图

    好吧,我承认确实没什么技术含量,作为一位已走出校园的程序员,是不屑于使用这种方法的。

    3.简洁分页,就是所谓的 ‘假’ 分页,试用对象,表中数据不多

       内部实现:每次操作均将表中数据全部查出,然后显示目的页

       ①.前端模板,定义样式(PS:模板来源网络)

        <div>
            <asp:GridView ID="GridV1" runat="server" PageSize="4" AllowPaging="true" OnPageIndexChanging="GridV1_PageIndexChanging">
                 <PagerTemplate>
                    当前第:          
                    <asp:Label ID="LabelCurrentPage" runat="server" Text="<%# ((GridView)Container.NamingContainer).PageIndex + 1 %>"></asp:Label>/共:            
                    <asp:Label ID="LabelPageCount" runat="server" Text="<%# ((GridView)Container.NamingContainer).PageCount %>"></asp:Label><asp:LinkButton ID="LinkButtonFirstPage" runat="server" CommandArgument="First" CommandName="Page"
                        Visible='<%#((GridView)Container.NamingContainer).PageIndex != 0 %>'>首页</asp:LinkButton>
                    <asp:LinkButton ID="LinkButtonPreviousPage" runat="server" CommandArgument="Prev"
                        CommandName="Page" Visible='<%# ((GridView)Container.NamingContainer).PageIndex != 0 %>'>上一页</asp:LinkButton>        
                    <asp:LinkButton ID="LinkButtonNextPage" runat="server" CommandArgument="Next" CommandName="Page"
                        Visible='<%# ((GridView)Container.NamingContainer).PageIndex != ((GridView)Container.NamingContainer).PageCount - 1 %>'>下一页</asp:LinkButton>
                    <asp:LinkButton ID="LinkButtonLastPage" runat="server" CommandArgument="Last" CommandName="Page"
                        Visible='<%# ((GridView)Container.NamingContainer).PageIndex != ((GridView)Container.NamingContainer).PageCount - 1 %>'>尾页</asp:LinkButton>
                    转到第<asp:TextBox ID="txtNewPageIndex" runat="server" Width="20px" Text="<%# ((GridView)Container.NamingContainer).PageIndex + 1 %>" /><%----这里将CommandArgument即使点击该按钮e.newIndex 值为3 --%>
                    <asp:LinkButton ID="btnGo" runat="server" CausesValidation="False" CommandArgument="-2"
                        CommandName="Page" Text="GO" OnClientClick="return textInt()"/>
                </PagerTemplate>
            </asp:GridView>
        </div>

    对于以上分页模板,只需要记住 ((GridView)Container.NamingContainer) 表示GridView控件本身,其余就不难理解

       PageIndex表示当前索引页

       PageCount加载控件后的数据总页数

    以上模板的设置可以处理首页、上一页、下一页、尾页功能

     ②.绑定数据,由于页面第一次加载和每次操作分页控件时,都是对数据的操作,所以最好是将其写在一个方法中,以便调用

      private void BindList() 
       {
         SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["IBBCConnectionString"].ToString());
    SqlDataAdapter sda
    = new SqlDataAdapter("SELECT * FROM IBCC.dbo.Student", con); con.Open(); DataSet ds = new DataSet(); sda.Fill(ds, "Temp"); GridV1.DataSource = ds.Tables["Temp"]; GridV1.DataBind(); con.Close(); }

     ③.处理跳转页,有时候执行跳转页,所填数字过大,或者不合法,对于这些情况,都需要进行处理,为了减少系统执行的复杂度,选择前台处理

        <script type="text/javascript">
            function textInt() {
                var reg = new RegExp("^[0-9]*$");
                var num = document.getElementById("GridV1_txtNewPageIndex");
                //得到控件总页数
                var count = document.getElementById("GridV1_LabelPageCount").innerHTML;
                //判断是否为数字
                if (!reg.test(num.value)) {
                    alert("not a number");
                    return false;
                }
                else {
                    num.value = parseInt(num.value) > parseInt(count) ? parseInt(count) : parseInt(num.value);
                    num.setAttribute("value", num.value);             
                }
            }
        </script>

     ④.后台处理逻辑跳转。给控件执行分页的操作设定索引页,非常简单

      protected void GridV1_PageIndexChanging(object sender, GridViewPageEventArgs e)
        {  
          //获得控件对象
          GridView grid = sender as GridView;
          //当前索引页
          if (e.NewPageIndex<0)
          {
            grid.PageIndex=int.Parse(((TextBox)GridV1.BottomPagerRow.FindControl("txtNewPageIndex")).Text) - 1;
          }
          else
          {
            grid.PageIndex = e.NewPageIndex;
          }         
           BindList();
        }

     所有步骤完成,进行调试,如下:

     所谓的假分页写到这里,有几个地方需要注意一下:

      ①前台获取asp控件时,有时候获取不到id,这个时候一般处理的方法有两种,一是运行程序,查看编译后该控件的id,例如,原来gridview1的id为txtNewPageIndex,运行程序经过HTML编译后变GridV1_txtNewPageIndex,多为加控件前缀;二是设置ASP控件时,增加ClientIDMode="Static",此时进行在运行项目,经HTML编译就不会更改该控件前缀,至于该属性的其他值,可以参考微软提供的信息

    4. 逻辑分页。就是所谓的真分页,适用于数据量大,不频繁执行分页操作

        内部实现,将查询的页数当作参数传递给后台的SQL,进行分页,而不是全部查出

        原理稍稍变化,仅此而已

        有时候可能遇到前台只显示部分列的情况,这个时候,需要在前台稍稍做一下处理,比如,如果使用 Repeater 控件来显示数据,设置如下

     <asp:Repeater ID="Repeater1" runat="server">
        <HeaderTemplate>
            <table  border="1" cellspacing="0" cellpadding="0">
                <tr>
                    <th>编号</th>                      
                    <th>日期</th>
                    <th>名稱</th>
                    <th>地址</th>
                 </tr>
        </HeaderTemplate>
        <ItemTemplate>
               <tr >
                   <td><%#DataBinder.Eval(Container.DataItem,"CUST_ID")%></td>                     
                   <td><%# ((System.Data.DataRowView)Container.DataItem)["JCIC_DATE"] %></td>                   
                   <td><%#Eval("C_NAME")%></td>
                   <td><%#Eval("ADDRESS")%></td>
               </tr>
        </ItemTemplate>
    </asp:Repeater>

    注:上图中"CUST_ID" 等列名一定要与数据库中的名字相同,其上的三种写法都是一样的效果

    5.引用开源控件,网上开源的分页控件有很多,如:MVC分页控件Webform分页控件

       MVC 引用分页控件,杨涛再其网站的说明文档中已有示例,这里简要记录几个关键点

       ① 安装NVC分页控件的 Nuget 包,微软的网有是很卡,我这里要稍稍吐槽下长城的网,卡的不行,一直都是安装失败,非得开VPN不可

       ② 控制器界面引用 using Webdiyer.WebControls.Mvc;

       ③ 视图界面引用 @model PagedList<TableName> ,视图文件只允许使用一个@model,如果创建的是强类型视图,最上面 @model IEnumerable<>需注销

        就目前开发而言,MVC也好,Webform也好,很少有手动书写分页控件的情况,多数公司也都有自己独立封装的控件,即使没有,也多为直接引用网上比较成熟的分页控件,学校教材教授的那些方法,实际上外面几乎是不用的。

    ----- 市人皆大笑 举手揶揄之

  • 相关阅读:
    java + jni + mingw实例开发(基于命令行窗口模式)
    OpenCv for Android
    Android图像处理实例教程
    eclipse使用技巧
    Android NDK开发实例教程
    Android开发的教程和资源
    JAVA安装,环境变量配置
    一些比较好的博客
    uwsgi启动Django项目时:unable to load app 0 (mountpoint='') (callable not found or import error) *** no app loaded. going in full dynamic mode ***
    robot中使用evaluate转化数据格式
  • 原文地址:https://www.cnblogs.com/Sientuo/p/6197871.html
Copyright © 2020-2023  润新知