asp.netMVC中实现分页方法

方法一:使用传统的sql语句实现分页,    public class UserprintDao如下

 
/// <summary>
        /// 取得用户申请记录列表(按分页)
        /// </summary>
        /// <param name="userid"></param>
        /// <param name="start"></param>
        /// <param name="end"></param>
        /// <returns></returns>
        public List<Userprint> GetUserReportListByUserId(Userprint userprint)
        {
            string sql =
                "select * from (select row_number() over(order by id desc) as num,* from userprint where userid=@userid ";
            if (!string.IsNullOrEmpty(userprint.Printname))
            {
                sql += " and printname like @printname";
            }
            sql += ") as t where t.num>=@start and t.num<=@end";
            return DoUserprintList(sql, userprint);
        }

//统一函数返回打印列表
        public List<Userprint> DoUserprintList(string sql, Userprint userprint)
        {
            try
            {
                using (SqlConnection conn = SqlHelper.GetConn())
                {
                    return conn.Query<Userprint>(sql, userprint).ToList<Userprint>();
                }
            }
            catch (Exception)
            {
                return null;
            }
        }
        //统一函数返回记录总数
        public int DoRecordCount(string sql,Userprint userprint)
        {
            try
            {
                using (SqlConnection conn = SqlHelper.GetConn())
                {
                    return conn.ExecuteScalar(sql, userprint).ToString().ToInt32();
                }
            }
            catch (Exception)
            {
                return 0;
            } 
        }
/// <summary>
        /// 取用户申请记录列表总数
        /// </summary>
        /// <param name="userprint"></param>
        /// <returns></returns>
        public int GetUserReportRecordCount(Userprint userprint)
        {
            string sql = "select count(1) from userprint where userid=@userid";
            SqlParameter[] para;
            if (!string.IsNullOrEmpty(userprint.Printname))
            {
                sql += " and printname like @printname";
            }
            return DoRecordCount(sql, userprint);
        }

控制器中如下

 public ActionResult ReprotManage()
        {
             Userprint tempuserprint = new Userprint();
            var keys = Request["keys"];
            if (!string.IsNullOrEmpty(keys))
            {
                tempuserprint.Printname = "%"+keys+"%";
            }
           
            tempuserprint.Userid = getUserBySession().Id;
            int pageIndex = Request["pageIndex"] == null ? 1 : Request["pageIndex"].ToInt32();

            int pageCount = GetPageCount(tempuserprint, pageSize, printdao.GetUserReportRecordCount);

            int start = (pageIndex - 1) * pageSize + 1;
            int end = pageIndex * pageSize;
            tempuserprint.start = start;
            tempuserprint.end = end;

            ViewData.Model = printdao.GetUserReportListByUserId(tempuserprint);
            ViewBag.pageIndex = pageIndex;
            ViewBag.pageCount = pageCount;
            return View();
        }
        //计算分页总数,使用委托合成一个函数
        public int GetPageCount(Userprint userprint, int pageSize, Func<Userprint, int> GetRecordCount)
        {
            return Math.Ceiling((double)GetRecordCount(userprint) / pageSize).ToString().ToInt32();
        }

在view视图添加分页代码,代码如下:

 <div class="text-center">@Html.Raw(Print.PageBar.GetPageBarToUlLi(ViewBag.pageIndex, ViewBag.pageCount))</div>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;


namespace Print
{
    public class PageBar
    {
        public static string GetPageBarToUlLi(int pageIndex, int pageCount)
        {
            if (pageCount <= 1)
            {
                return string.Empty;
            }
            int start = pageIndex - 5;
            start = start < 1 ? 1 : start;
            int end = start + 9;
            end = end > pageCount ? pageCount : end;
            StringBuilder sb = new StringBuilder();
            sb.Append("<nav><ul class='pagination'><li");
            if (pageIndex == 1)
                sb.Append(" class='disabled'");
            sb.Append("><a href='?pageIndex=1' aria-label='Previous'><span aria-hidden='true'>").Append("第一页").Append("</span></a></li>");

            for (int i = start; i <= end; i++)
            {
                if (i == pageIndex)
                    sb.Append("<li class='active'><a href=javascript:void(0)>" + i + "</a></li>");
                else
                {
                    sb.Append(string.Format("<li><a href=?pageIndex={0}>{0}</a></li>", i));
                }
            }
            sb.Append("<li");
            if (pageIndex == pageCount)
                sb.Append(" class='disabled'");
            sb.Append("><a href='?pageIndex=").Append(pageCount).Append("' aria-label='Next'> <span aria-hidden='true'>最后一页</span></a></li></ul></nav>");
            return sb.ToString();
        }
        public static string GetPageBar(int pageIndex, int pageCount)
        {
            if (pageCount <= 1)
            {
                return string.Empty;
            }
            int start = pageIndex - 5;
            start = start < 1 ? 1 : start;
            int end = start + 9;
            end = end > pageCount ? pageCount : end;
            StringBuilder sb = new StringBuilder();
            sb.Append("<a href=?pageIndex=1>第一页</a>");
            for (int i = start; i <= end; i++)
            {
                if (i == pageIndex)
                    sb.Append(" " + i + " ");
                else
                {
                    sb.Append(string.Format("<a href=?pageIndex={0}>{0}</a>", i));
                }
            }
            sb.Append(string.Format("<a href=?pageIndex={0}>最后一页</a>", pageCount));
            return sb.ToString();
        }
    }
}

写的有点乱,这是从项目中复制出来的,其中使用到了ORM框架Dapper, js库jquery,UI美化:bootstrip,自行添加。

效果图如下:

方法二:使用第三方库PageList,添加引用 ,使用NuGet添加:PagedList,同时也会添加PagedList.Mvc

在控制器中实现如下代码:

  public ActionResult Index(SearchInfo info, int page = 1){

   var result=(from p in db.userprints select p).OrderByDescending(m => m.addtime).ToPagedList(page, 17);
   if (Request.IsAjaxRequest())
           return PartialView("_statislist", statis);    
return View(result); }

在主视图中代码:

<div class="col-md-10">
            @Html.Partial("_statislist", Model)
        </div>

部分视图_statislist.cshtml代码如下:

@using PagedList.Mvc
@model IPagedList<Print.Entity.userprint>
          
<div id="statislist">
    <div class="pagedList" >
        @Html.PagedListPager(Model,page=>Url.Action("Index",new{page}),PagedListRenderOptions.Classic)
    </div>
    <table class="table table-hover table-striped">
        <tr>
            <th>
                文印名称
            </th>
            <th>
                打印色彩
            </th>
            <th>
                单双面
            </th>
          
            <th>
                纸张大小
            </th>
           
            
        </tr>

        @foreach (var item in Model)
        {
            <tr>
                <td>
                    @Html.DisplayFor(modelItem => item.printname)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.printcolor)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.printmode)
                </td>
             
                <td>
                    @Html.DisplayFor(modelItem => item.printpagersize)
                </td>
               
            </tr>
        }
    </table>
</div>

为分页添加样式,此代码放在主视图就行

<script>
    $(function () {
       
        $(".pagedList a").click(function () {
            $.ajax({
                url: $(this).attr("href"),
                data: $("form").serialize(),
                type: "get"
            }).done(function (data) {
                $("#statislist").replaceWith(data);
            });
        });
    });
</script>

效果如下:

 

PageList分页功能很强大,但是在实际使用中经常与查询在一起使用,如果对查询结果操作分页时,发现后面分页全乱了,最终想了一个办法解决,本人认为这样比较麻烦,但可以解决问题。思路就是:把查询的条件在页面与后台间传递。以显示用户信息为例,利用PagedLilst实现查询+分页:

1.创建类UserAndPagedList,收集后台所有传递的信息

namespace Course.Entity
{
    public class UserAndPagedList
    {
        public User User { get; set; }
        public IPagedList<User> Users { get; set; }
    }
}

2.ActionResult

public ActionResult List(User user, int page = 1)
        {
            IPagedList<User> list;
            if (string.IsNullOrEmpty(user.name))
                list = db.Users.Where(u => u.userlevel != 2).OrderByDescending(u => u.registertime).ToPagedList<User>(page, 2);
            else
                list = db.Users.Where(u => u.userlevel != 2).Where(u => u.name.Contains(user.name)).OrderByDescending(u => u.registertime).ToPagedList<User>(page, 2);
            UserAndPagedList objModel = new UserAndPagedList()
            {
                User = user,
                Users = list
            };

            return View(objModel);
        }

3.View

@using PagedList.Mvc
@using Course.Entity
@model Course.Entity.UserAndPagedList
@{
    ViewBag.Title = "List";
    Layout = "~/Views/Shared/AdminLayout.cshtml";
}
<style>
    td {
        font-size: 14px;
    }
</style>
@using (Html.BeginForm("List", "Admin", new AjaxOptions() { UpdateTargetId = "userlist", HttpMethod = "post", InsertionMode = InsertionMode.Replace }))
{
    <input name="name" id="name" placeholder="用户名" class="form-control line" />
    <button class="btn btn-success" type="submit">查询</button>
}

@Html.Partial("_userlist", Model); //视图
<script>
    $(function () {
        $("#name").width("200px").val('@Model.User.name'); //填充查询条件
        $(":submit").width("60px");
    })
</script>

4.部分视图_userlist

@using PagedList.Mvc
@using Course.Entity
@model Course.Entity.UserAndPagedList

<div id="userlist">
    <div class="pagedList">      
        @Html.PagedListPager(Model.Users, page => Url.Action("List", new { page, Model.User.name}), PagedListRenderOptions.Classic)
    </div>
    <table class="table table-hover table-striped">
        <tr>
            <th width="150">
                用户名
            </th>
            <th width="100">
                用户类型
            </th>
            <th width="150">
                操作
            </th>
        </tr>

        @foreach (var item in Model.Users)
        {
            <tr>
                <td>
                    @Html.DisplayFor(modelItem => item.name)
                </td>

                <td>
                    @(item.userlevel == 2 ? "管理员" : item.userlevel == 1 ? "教员" : "学生")
                </td>

                <td>
                    @Html.ActionLink("编辑", "Edit", new { id = item.name })
                    @Ajax.ActionLink("删除", "Delete", new { id = item.name }, new AjaxOptions() { Confirm = "确定要删除吗?", OnSuccess = "afterOk" })
                </td>

            </tr>
        }
    </table>
</div>

<script>
    function getValue() {
        return $("#name").val();
    }

    function beginOk(data) {
        if (!confirm("是否要删除?")) {
            return false;
        }
    }
    function afterOk(data) {
        var arr = data.split(":");
        if (arr[0] == "ok") {
            $("table tr td:contains(" + arr[1] + ")").parent().remove();
        }
        else
            alert("无法删除");
    }
</script>

关键部位用绿色作标记了,

 

下面再来一个用查询+分页的例子,不过这次是在页码上作点手脚,分页时使用ajax提交,这样分页与列表部分就实现异步提交了,这个的实现刚开始走了不少弯路,实现如下:

页面上有两块,一块是查询条件,另一块是显示查询列表,列表的设计是放在分部视图中,页码也是分部视图中,代码如下:

Controllers

 public ActionResult ManageCourse(Courseware cw, int firstdirectoryid = 0, int page = 1)
        {
//第一次加载数据
            ViewBag.firstDir = new SelectList(
                db.Firstdirectories.OrderBy(m => m.sort)
                    .Select(m => new { id = m.id, title = m.title }).ToList()
                , "id", "title");

            ViewBag.coursetype = new SelectList(
                db.Contenttypes
                    .Select(m => new { id = m.id, name = m.name }).ToList()
                , "id", "name");
            var list = (from c in db.Coursewares
                        orderby c.seconddirectoryid, c.sort
                        select c).ToPagedList<Courseware>(page, 16);
            return View(list);

        }
//分部视图
public ActionResult SysManageCourse(Courseware cw, int firstdirectoryid = 0, int page = 1) { var list = db.Coursewares.Where(x => x.id != 0); if (firstdirectoryid != 0) { if (cw.seconddirectoryid != 0) { list = list.Where(x => x.seconddirectoryid == cw.seconddirectoryid); } else { list = list.Where(x => x.Seconddirectory.firstdirectoryid == firstdirectoryid); } } if (cw.contenttypeid != 0) { list = list.Where(x => x.contenttypeid == cw.contenttypeid); } if (!string.IsNullOrEmpty(cw.title)) { list = list.Where(x => x.title.Contains(cw.title)); } var obj = list.OrderBy(x => x.seconddirectoryid).ThenBy(x => x.sort).ToPagedList<Courseware>(page, 16); return PartialView("_courselist", obj); }

主View--ManageCourse.cshtml

@using PagedList.Mvc
@model PagedList.IPagedList<Course.Entity.Courseware>

@{
    ViewBag.Title = "ManageCourse";
    Layout = "~/Views/Shared/TeacherLayout.cshtml";
}
<style>
    td {
        font-size: 14px;
    }
</style>
@using (Ajax.BeginForm("SysManageCourse", "Teacher", new AjaxOptions() { UpdateTargetId = "divlist", HttpMethod = "post", InsertionMode = InsertionMode.Replace }, new { @class = "form-inline" }))
{
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true)
    <table>
        <tr>
            <td>
                <div class="form-group">
                    <label for="firstdirectoryid">选择目录:</label>
                    @Html.DropDownList("firstdirectoryid", ViewBag.firstDir as SelectList, "", new { @class = "form-control" })
                </div>
                <div class="form-group">
                    <label for="seconddirectoryid">小节名称:</label>
                    <select class="form-control" id="seconddirectoryid" name="seconddirectoryid"></select>
                </div>
            </td>
        </tr>
        <tr><td height="10px"></td></tr>
        <tr>
            <td>
                <div class="form-group">
                    <label for="title">&nbsp;&nbsp;&nbsp;&nbsp;小标题:</label>
                    <input name="title" id="title" style="width: 300px" />
                </div>
                <div class="form-group">
                    <label for="contenttypeid">课件类型:</label>
                    @Html.DropDownList("contenttypeid", ViewBag.coursetype as SelectList, "", new { @class = "form-control" })
                </div>
                <input type="submit" class="btn btn-success" value="查询" />

            </td>
        </tr>
    </table>
}

<hr />

<div id="pagedPartialView">
    @Html.Partial("_courselist", Model)
</div>
<script>
  
    $(function () {
        
        $("input").addClass("form-control").focus(function () {
            $(this).select();
        });
        $("#contenttypeid").width(50);

        $("#firstdirectoryid").change(function () {
            var value = $(this).val();
            if (value == "")
                $("#seconddirectoryid").val("");
            else {
                $.getJSON("GetSecondDirectoryByfirstDirectoryid", { id: $(this).val() }, function (data) {
                    $("#seconddirectoryid option").remove();
                    $("<option></option>").appendTo("#seconddirectoryid");
                    $.each(data, function (i, v) {
                        $("<option value='" + v.id + "'>" + v.title + "</option>").appendTo("#seconddirectoryid");
                    });

                });
            }
        });
    });
    function modify(mid, firid, title, sort) {
        $("#id").val(mid);
        $("#firstdirectoryid").val(firid);
        $("#title").val(title);
        $("#sort").val(sort);
        $(":submit").val("修改");
    }
    function beginOk() {
        if (!confirm("是否要删除?")) {
            return false;
        }
    }
    function afterOk(data) {
        var arr = data.split(":");
        if (arr[0] == "ok") {
            $("table tr td:contains(" + arr[1] + ")").parent().remove();
        }
        else
            alert("无法删除");
    }
    //function afterOk(data) {
    //    var arr = data.split(":");
    //    if (arr[0] == "ok") {
    //        $("table tr").each(function () {
    //            if ($(this).data("delid") == arr[1]) {
    //                $(this).remove();
    //            }
    //        });
    //    }
    //    else
    //        alert("无法删除");
    //}
    
</script>

分部视图--_courselist.cshtml

@using PagedList.Mvc
@model PagedList.IPagedList<Course.Entity.Courseware>

<div id="divlist">

    <div class="pagedList">
            @Html.PagedListPager(Model, page => Url.Action("SysManageCourse", new { page }), PagedListRenderOptions.Classic)
        </div>
    @*@Html.PagedListPager(Model, page => Url.Action("SysManageCourse", new { page }),
        new PagedListRenderOptions()
        {
            LinkToFirstPageFormat = "首页",
            LinkToNextPageFormat = "下一页",
            LinkToPreviousPageFormat = "上一页",
            LinkToLastPageFormat = "末页",
            DisplayItemSliceAndTotal = true,
            ItemSliceAndTotalFormat = "共有{2}页",
            MaximumPageNumbersToDisplay = 6
        })*@

    <table class="table table-hover table-striped">
        <tr>
            <th width="150" class="text-center">
                操作
            </th>
            <th width="100">
                序号
            </th>
            <th width="100">
                类型
            </th>

            <th>
                标题
            </th>
        </tr>

        @foreach (var item in Model)
        {

            <tr>
                <td class="text-center" width="150">
                    @Html.ActionLink("编辑", "EditCourse", new { id = item.id }) |
                    @Html.ActionLink("详细", "DetailsCourse", new { id = item.id }) |
                    @Ajax.ActionLink("删除", "DeleteCourse", new { id = item.id }, new AjaxOptions() { Confirm = "确定要删除吗?", HttpMethod = "post", OnSuccess = "afterOk" })
                </td>
                <td width="100">@Html.DisplayFor(modelItem => item.sort)</td>
                <td width="100">
                    @Html.DisplayFor(modelItem => item.Contenttype.name)
                </td>
                <td>@Html.DisplayFor(modelItem => item.title)</td>
            </tr>
        }
    </table>

</div>
<script>
    $(function () {
        $("#divlist>.pagedList>.pagination-container li a[href]").click(function () {
            var href = $(this).attr("Href");
                $.post(href, $("#form0").serialize(), function (data) {
                    $("#pagedPartialView").html(data);
                });
            return false;
        });
    });
</script>

代码中有多余的内容,由于是直接复制过来,自己挑着看,要注意的是在分部视图中对页码的click事件(就是上面绿色的部分,屏蔽点击直接跳转,用异步ajax跳转)一定要写在分部视图中,如果写在主视图中那就惨了,点击页面会直接跳转,根本就不经过JS,原因时ajax分页后返回数据重写了分部视图中的所有元素,前面的JS对后面重写的不起作用,所以一定要写在分部视图中,刚开始我就是把它写在了主视图中,折腾1个小时才明白。$.post提交时把查询块form中的数据传递给了后台。

 

另外提供两种分页方式:

<div class="pagedList">
            @Html.PagedListPager(Model, page => Url.Action("SysManageCourse", new { page }), PagedListRenderOptions.Classic)
        </div>
@Html.PagedListPager(Model, page => Url.Action("SysManageCourse", new { page }),
        new PagedListRenderOptions()
        {
            LinkToFirstPageFormat = "首页",
            LinkToNextPageFormat = "下一页",
            LinkToPreviousPageFormat = "上一页",
            LinkToLastPageFormat = "末页",
            DisplayItemSliceAndTotal = true,
            ItemSliceAndTotalFormat = "共有{2}页",
            MaximumPageNumbersToDisplay = 6
        }

 

posted @ 2015-05-12 18:09  lunawzh  阅读(1883)  评论(0编辑  收藏  举报