Asp.net MVC 分页控件

      项目使用Asp.net MVC有一段时间了,刚开始的时候,非常不适应,很多在webform中非常习惯的用法和技巧,在这里都做不出来,显得束手束脚,不过写起来倒是找回了一些写jsp代码的感觉。 - -

      好吧,闲话不多说,进入正题,讲下我使用的MVC分页控件吧!

      首先,我自己在写分页控件之前,找过一些资料,排名比较靠前的,就有以下这篇博客:asp.net mvc强大的分页控件MvcPager,它整理了一些封装得较为完善的分页控件的链接,其中,杨涛的博客的示例列举比较多,杨涛个人主页:www.webdiyer.com

      我研究了他里面列出来的ajax分页控件的示例,并引入我的项目中。

      赞美!这个分页控件使用起来非常非常之方便,封装比较完美了,只要将需要引用的动态链接库文件全部引用进来,并且为分页控件指定正确的参数,即可使用,分页控件各按钮的Url定义,页码的计算,以及取记录的操作全部封装好,无须我们另外定义。为了偷懒,我还向我老大强力推荐这款“懒惰”的分页控件,不过因为一个原因,这个分页控件最终在项目中被排除了。

      它在设计上有一个令人可恨的特性——它的分页操作在客户端缓存中进行(这也是它使用起来如此简单的一个原因之一)。当数据量庞大时,它的性能将令人难以忍受。于是,它被果断抛弃。

      我只得自己写了一个较简陋的分页控件,简陋,意味着你需要为它写更多的代码。几乎没有BUG,而且在设计上,也没有太多的诟病,当然,它也有一个缺憾:当页面包含较多的过滤条件时,需要你针对这些查询条件做一些特别处理。换句话说,由于分页控件的“首页、下一页、上一页、末页、跳转_页”使用超链接的方式传递参数,导致,在查询条件较多的时候,需要你自行拼接查询条件,例如:“王#2010-10-01#1#4”(某些人也许做过同样的事情,应该看得懂这个)。

      接下来,介绍一下这个分页控件的原理吧!

      1. 这个分页控件完全与展示数据的控件分离,它们之间没有任何耦合,并且它只负责显示一些分页信息(总页数、记录条数、每页记录条数),和与翻页相关的按钮的跳转。

      2. 你需要为它写一个action,所有的翻页查询数据、包括第一次进入页面查询数据都通过该action来完成。

      3. 需要准备一个获取分页数据的存储过程。

      然后,我再列出我的一些代码吧!

      [分页控件]

     

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>

<style type="text/css">
    .Statistics
    {
        height: 35px;
        vertical-align: middle;
        width: 100%;
        line-height: 22px;
        text-align: left;
        padding-left: 11px;
        font-family: Tahoma;
        text-align: right;
        padding-bottom: 3px;
        padding-top: 3px;
        padding-right: 10px;
    }
    .StatisticsNumeric
    {
        margin-left: 4px;
        margin-right: 4px;
        font-weight: Bold;
        color: #690;
        font-size: 14px;
    }
    .NavigationArea
    {
        border-bottom: #ddd 1px solid;
        text-align: left;
        padding-bottom: 10px;
        margin: 5px 3px 5px 0px;
        padding-left: 3px;
        padding-right: 3px;
        font-family: Tahoma;
        display: block;
        clear: left;
        font-size: 14px;
        padding-top: 10px;
    }
    .NavigationArea a
    {
        text-decoration: none;
        padding-bottom: 5px;
        padding-left: 8px;
        padding-right: 8px;
        padding-top: 5px;
    }
    .NavigationArea a:hover
    {
        border-bottom: #690 2px solid;
        color: #690;
        text-decoration: none;
    }
    .page_a_NumericButton
    {
        color: #000000;
    }
    .page_a_disabled
    {
        color: #999999;
    }
    .page_a_current
    {
        border-bottom: #690 2px solid;
        color: #690;
        font-weight: 700;
    }
    .button_go
    {
        border: none;
        background: #FFFFFF;
        font-family: Tahoma;
        border: solid 1px #CCCCCC;
    }
    .textbox_pageIndex
    {
        font-family: Tahoma;
        width: 45px;
        border: solid 1px #CCCCCC;
        margin-left: 5px;
        margin-right: 5px;
    }
    .page_span_text
    {
        font-family: Tahoma;
        font-size: 13px;
    }
    .textNumber
    {
        font-weight: Bold;
        color: #690;
        font-size: 12px;
    }
    .currentSpan
    {
        border: solid 1px #f34500;
        color: #fff;
        background: #f34500;
        padding: 2px 5px;
        font-weight: bold;
        margin: 2px;
    }
    .Span
    {
        border: #aaaadd 1px solid;
        padding: 2px 5px;
        text-decoration: none;
        color: #000;
        cursor: pointer;
    }
</style>
<script type="text/javascript">
    function setPageSize() {
        var pz = $('#pageSizeList').val();
        var url = window.location.href;
        if (url.toUpperCase().indexOf('PAGESIZE=') < 0 || url.toUpperCase().indexOf('PAGEINDEX=') < 0) {
            window.location.href = url + '?PageSize=' + pz + '&PageIndex=1';
            return;
        }
        // “PageSize=”后面的部分
        var url_part = url.substring(url.toUpperCase().indexOf('PAGESIZE=') + 9, url.length);
        var ps = getNumber(url_part);
        url = url.replace("PageSize=" + ps, "PageSize=" + pz);

        window.location.href = url;
    }

    function setPageIndex(pageIndex) {
        var url = window.location.href;
        var pz = $('#pageSizeList').val();
        if (url.toUpperCase().indexOf('PAGESIZE=') < 0 || url.toUpperCase().indexOf('PAGEINDEX=') < 0) {
            window.location.href = url + '?PageSize=' + pz +'&PageIndex=' + pageIndex;
            return;
        }
        var url_page = url.substring(url.toUpperCase().indexOf('PAGEINDEX=') + 10, url.length);
        var pi = getNumber(url_page);
        url = url.replace("PageIndex=" + pi, "PageIndex=" + pageIndex);

        window.location.href = url;
    }

    function gotoPage(pageCount) {
        var gotopageindex = $('#gotoPage').val();
        if (Number(gotopageindex) > Number(pageCount)) {
            gotopageindex = pageCount;
        } else if (Number(gotopageindex) < 1) {
            gotopageindex = '1';
        }

        var pz = $('#pageSizeList').val();
        var url = window.location.href;
        var url_part = url.substring(url.toUpperCase().indexOf('PAGESIZE=') + 9, url.length);
        var ps = getNumber(url_part);
        url = url.replace("PageSize=" + ps, "PageSize=" + pz);

        url_page = url.substring(url.toUpperCase().indexOf('PAGEINDEX=') + 10, url.length);
        var pi = getNumber(url_page);
        url = url.replace("PageIndex=" + pi, "PageIndex=" + gotopageindex);

        window.location.href = url;
    }

    function getNumber(part) {
        var str = "0123456789";
        var rst = '';
        for (var i = 0; i < part.length; i++) {
            if (str.indexOf(part.charAt(i)) < 0)
                break;
            rst += part.charAt(i);
        }

        return rst;
    }
</script>
<%
    var data = ViewData["PageData"];
    if (data != null)
    {
        int pageIndex = Convert.ToInt32(ViewData["PageIndex"] ?? "0");      // 页码
        int pageSize = Convert.ToInt32(ViewData["PageSize"] ?? "0");        // 每页显示记录条数
        int pageCount = Convert.ToInt32(ViewData["PageCount"] ?? "0");      // 总页数
        int recordCount = Convert.ToInt32(ViewData["RecordCount"] ?? "0");  // 总记录数
        int lastPageIndex = (pageIndex - 1 < 1) ? 1 : pageIndex - 1;
        int nextPageIndex = (pageIndex + 1 > pageCount) ? pageCount : pageIndex + 1;
%>
<table class="Statistics">
    <tr>
        <td align="left" style="padding-left: 20px" id="perPage">
            每页显示数量 <select id="pageSizeList" class="PzSelect" οnchange="setPageSize()">
                <option value="10">10</option>
                <option value="20">20</option>
                <option value="30">30</option>
            </select>
            <input type="hidden" id="fPageSize" value="<%= pageSize %>" />
            <input type="hidden" id="fPageIndex" value="<%= pageIndex %>" />
        </td>
        <td align="right">
            共<span class="StatisticsNumeric"><%= recordCount  %></span>条记录    
            当前页:<span class="StatisticsNumeric"><%= pageCount==0?0:pageIndex%></span>/<span
                class="StatisticsNumeric"><%= pageCount%></span>        
            <%
        if (pageIndex == 1)
        {
            if (pageCount == 1 || pageCount == 0)
            {
            %>
            <a style="color: #999999">首页</a> <a style="color: #999999">上一页</a> <a style="color: #999999">
                下一页</a> <a style="color: #999999">末页</a>
            <%
            }
            else
            {
            %>
            <a style="color: #999999">首页</a> <a style="color: #999999">上一页</a> <a href="javascript:setPageIndex('<%= nextPageIndex %>');">
                下一页</a> <a href="javascript:setPageIndex('<%= pageCount %>');">
                    末页</a>
            <%
            }
        }
        else if (pageIndex == pageCount)
        { 
            %>
            <a href="javascript:setPageIndex('1');">
                首页</a> <a href="javascript:setPageIndex('<%= lastPageIndex %>');">
                    上一页</a> <a style="color: #999999">下一页</a> <a style="color: #999999">末页</a>
            <%
        }
        else
        { 
            %>
            <a href="javascript:setPageIndex('1');">
                首页</a> <a href="javascript:setPageIndex('<%= lastPageIndex %>');">
                    上一页</a> <a href="javascript:setPageIndex('<%= nextPageIndex %>');">
                        下一页</a> <a href="javascript:setPageIndex('<%= pageCount %>');">
                            末页</a>
            <%  
        }
            %>
            转到第
            <input type="text" class="textNumber" style="width: 30px" id="gotoPage" />
            页  <a href="javascript:gotoPage('<%= pageCount%>');">跳转</a>
        </td>
    </tr>
</table>
<script type="text/javascript">
    $(function () {
        // 设置分页Size
        $("#pageSizeList").val('<%= pageSize %>');
    });
</script>
<%
    }        
%>


 

      [PageEn.cs]

     

using System;
using System.Collections.Generic;
using System.Collections;

namespace ATA.Toeic.Models
{
    [Serializable]
    public class PageEn
    {
        private int? _pageIndex;        // 页码
        private int? _pageSize;         // 每页记录条数
        private int? _recordCount;      // 总记录条数
        private int? _pageCount;        // 页数
        private string _condition;      // 条件
        private int? _goToPageIndex;    // 跳转到
        private bool _isShow;           // 是否显示
        private IList _pagedata;        // 分页数据
        private string _pageurl;        // 翻页链接

        public string PageURL
        {
            set { _pageurl = value; }
            get { return _pageurl; }
        }

        public IList PageData
        {
            set { _pagedata = value; }
            get { return _pagedata; }
        }

        public int? PageIndex
        {
            set { _pageIndex = value; }
            get { return _pageIndex; }
        }

        public int? PageSize
        {
            set { _pageSize = value; }
            get { return _pageSize; }
        }

        public int? RecordCount
        {
            set { _recordCount = value; }
            get { return _recordCount; }
        }

        public int? PageCount
        {
            set { _pageCount = value; }
            get { return _pageCount; }
        }

        public int? GoToPageIndex
        {
            set { _goToPageIndex = value; }
            get { return _goToPageIndex; }
        }

        public string Condition
        {
            set { _condition = value; }
            get { return _condition; }
        }

        public bool IsShow
        {
            set { _isShow = value; }
            get { return _isShow; }
        }
    }
}


 

      [分页action]

/// <summary> 
/// 获取分页数据 
/// </summary> 
/// <param name="PageIndex">页码</param> 
/// <param name="Condition">查询条件拼接串</param> 
/// <returns></returns>
public ActionResult ViewExamServiceList(int? PageIndex, string Condition) 
{ 
    // 获取分页数据的方法,页码不提供时,默认为第一页,Condition条件可以在数据访问层,拼接成查询条件,PAGE_SIZE可以在web.config中配置 
    PageEn pen = new ExamServiceBLL().GetExamServiceByPage(PageIndex ?? 1, PAGE_SIZE, this.UserId, Condition); 
    pen.Condition = Condition; 
    pen.PageURL = Url.Action("ViewExamServiceList", "ExamService"); 
    // ExamServiceList这个视图包含MVCPage分页控件和展示数据的控件 
    return View("ExamServiceList", pen); 
} 


 

      [ViewExamServiceList.aspx]

     

 

      [获取分页数据的存储过程]

    

  
-- =============================================          
-- Author:            
-- Create date:       
-- Description: 分页SP
-- =============================================                    
CREATE procedure [dbo].[SP_GetPage]                    
    @tblName   varchar(1000),       -- 表名                    
    @strGetFields varchar(1000) = '*',  -- 需要返回的列                    
    @strOrder varchar(100)='',      -- 排序的字段名                    
    @PageSize   int = 10,          -- 页尺寸                    
    @PageIndex  int = 1,           -- 页码                    
    @strWhere  varchar(1500) = '',  -- 查询条件 (注意: 不要加 where)                    
    @sort varchar(5) ='asc',                    
    @RowCount int output                                         
AS      
begin              
   declare @strSQL   varchar(5000)                    
   declare @DynamicSQL nvarchar(4000)                    
   if @strWhere !=''     
   begin             
      set @strWhere=' where '+@strWhere                  
   end
   SET @DynamicSQL = N'select @RowCount = count(*) from '+@tblName+@strWhere          
   exec sp_executesql @DynamicSQL, N'@RowCount int OUTPUT',@RowCount OUTPUT                    
   set @strSQL='SELECT   * FROM (SELECT ROW_NUMBER() OVER (Order By '+@strOrder+' '+@sort+') AS pos,'+@strGetFields+' FROM '+@tblName+@strWhere+') AS sp WHERE pos BETWEEN '+str((@PageIndex-1)*@PageSize+1)+' AND '+str(@PageIndex*@PageSize)                    
   exec (@strSQL) 
end
go


     为此,你需要在DAL里面将存储过程的参数拼接好,举一个简单的调用YX_ShowPage的示例,就知道这个过程要怎么用了:

     declare @recordCount  int

     exec YX_ShowPage ' V_YX_ExamService ', ' * ', ' fServiceId ',  10, 1, '', 'desc',  @recordCount output           

 

     [效果图]

    

 

      以上,只是分页控件的一些思路,控件相对比较粗糙,没有什么技术含量,只是它也有一定程度的实用性,至少在性能上没有什么令人诟病的地方,或许大家会有更好的解决办法,或许大家能在此基础上,写出更方便,封装更好的控件。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值