我要学ASP.NET MVC 3.0(十六): MVC 3.0 实例系列之表格数据的分页
概述
上节我们学习了如何在MVC 3应用程序中实现一个简单表格并在表格之中加上了排序的表头,使我们的表格在使用起了更加人性化,这些都是使用了MVC 3.0的相关特性来完成的。
我们在程序中添加了一个辅助类EmployeeGridModel,来显示我们的Grid的数据,包括所有要传递及初始化的数据,在表格排序的时候起到了很大的作用,同样的我们在分页的时候也需要这样的辅助类。
这节我们继续使用MVC的新特性来为Grid中的数据添加分页功能,有了分页功能,表格就不会显得单调,显示起来就更加有美感。
问题分析
通过上节的学习我们知道,在MVC 程序中使用参数可以实现排序,那么我们使用参数怎么实现分页呢?分页有需要那些参数呢?
首先:作为一个表格我们必须知道他总共有多少条数据TotalRecordCount,每页显示几条数据PageSize,这样就确定了表格的总页数PageCount
其次:我们要知道表格中的数据要从哪一页开始索引显示CurrentPageIndex
这样我们就初步把一些参数设想出来了,为了简单期间,我们每页默认显示5条数据,你也可以设置成你想要的值。而数据总条数可以从数据库中得到,
总结后得出参数:
①page当前页:当前表格索引页。
②pageSize每页显示条数:当前表格中显示几条数据。
修改辅助类
修改Model文件夹的EmployeeGridModel类
向类中添加如下代码(以前的代码不变后续功能要使用)
......................................
public EmployeeGridModel()
{
//默认值 每页显示5条记录 从第1页开始
this.PageSize = 5;
this.CurrentPageIndex = 1;
}
/// <summary>
/// 当前页的索引
/// </summary>
public int CurrentPageIndex { get; set; }
/// <summary>
/// 每页显示的记录条数
/// </summary>
public int PageSize { get; set; }
/// <summary>
/// 总记录条数
/// </summary>
public int TotalRecordCount { get; set; }
/// <summary>
/// 分页总数
/// </summary>
public int PageCount
{
get
{
if (TotalRecordCount % PageSize == 0)
{
return TotalRecordCount / PageSize;
}
else
{
return TotalRecordCount / PageSize + 1;
}
}
}
在这里我们设置了分页默认每页显示5条记录,从第一页开始显示。
创建Action
在EmployeeController添加名为Paged的方法
该方法包含两个参数page和pageSize
代码如下
public ActionResult Paged(int page = 1, int pageSize = 5)
{
var model = new EmployeeGridModel
{
CurrentPageIndex = page,
PageSize = pageSize,
//确定记录总数(才能计算出PageCount页数)
TotalRecordCount = this.DataContext.Employee.Count()
};
// 获取当前页的信息
model.Employees = this.DataContext.Employee
.Skip((model.CurrentPageIndex - 1) * model.PageSize)
.Take(model.PageSize);
return View(model);
}
首先我们初始化一个辅助类EmployeeGridModel,读取了数据库中表的记录条数,为相关属性设置默认值,返回一个辅助类的Employeelist
注意:此处我们的OrderBy可以参照上篇中的具体操作,这里就不多赘述。
创建视图View
为Paged的Action添加一个视图View,选择强类型为EmployeeGridModel
修改代码为
@model MVC3.Grid.Models.EmployeeGridModel
@{
ViewBag.Title = "Paged";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>分页列表</h2>
<p>
<i>总共有 @Model.TotalRecordCount 条记录,每页显示 @Model.PageSize 条</i>
<i>你正在查看的是 @Model.PageCount 页的第 @Model.CurrentPageIndex 页</i>
</p>
<table border="1" width="100%" style="text-align: center; border-collapse: collapse">
<tr>
<th>编号</th>
<th>姓名</th>
<th>性别</th>
<th>生日</th>
<th>是否婚配</th>
</tr>
@foreach (var item in Model.Employees)
{
<tr>
<td>@item.EmployeeNO</td>
<td>@item.EmployName</td>
<td>@item.Sex</td>
<td>@item.Birthday</td>
<td>
@if (item.Marital == "1")
{
@:@("是")
}
@if (item.Marital != "1")
{
@:@("否")
}
</td>
</tr>
}
<tr>
<td colspan="5">
 
</td>
</tr>
</table>
这样一来,我们的页面基本就算是做好了,运行起来看看
此时我们的表格数据基本已经是完成了的,每页显示5条,从第一页开始,数据都跟数据库完全符合。好下面我们继续来学习如何创建分页控件。
创建分页链接
首先我们看看一般的分页控件是怎么形态
我们可以看到分页控件是由一个一个的分页链接来组成的,每点击一次就有不同的数据筛选出来。
下面我们就创建分页链接
鼠标右击Shared文件夹--新建--视图
新建名为_SmartLink的分部视图
选择强类型视图EmployeeGridModel
修改_SmartLink代码为
@model MVC3.Grid.Models.EmployeeGridModel
@{
//文本编写器
var razorWriter = ViewContext.Writer;
//判断当前链接是否选中
if ((bool)ViewData["Inactive"])
{
//将当前的Text输出 加入了css样式 该样式可以写在样式表、母版页、当前页中
razorWriter.Write(string.Format("<span class=\"{0}\">{1}</span>", "pagerButtonDisabled", ViewData["Text"]));
}
else
{
//路由参数
var routeData = new RouteValueDictionary { { "page", ViewData["PageIndex"].ToString() }, { "pageSize", Model.PageSize } };
var htmlAttributes = new Dictionary<string, object>();
//判断是否为选中状态 添加CSS样式
if ((bool)ViewData["Selected"])
{
htmlAttributes.Add("class", "pagerButtonCurrentPage");
}
else
{
htmlAttributes.Add("class", "pagerButton");
}
var linkMarkup = Html.ActionLink(
ViewData["Text"].ToString(), // 超链接文本
Html.ViewContext.RouteData.Values["action"].ToString(), // Action
Html.ViewContext.RouteData.Values["controller"].ToString(), // Controller
routeData, // 路由参数
htmlAttributes // HTML属性适用于超链接
).ToHtmlString();
razorWriter.Write(linkMarkup);
}
}
上面的代码注意就是判断当前的链接是否被选中,如果选中就执行Action方法添加CSS样式,否则就输出Html内容
然后为Site.css样式表添加一些样式,保证代码的完整性
a.pagerButton, a.pagerButton:visited
{
border: solid 0px black;
padding: 1px;
text-decoration: none;
color: #006;
margin: 0px 1px 0px 1px;
}
a.pagerButton:hover
{
border: solid 1px red;
color: Black;
}
a.pagerButtonCurrentPage
{
border: solid 1px #00a;
padding: 1px;
text-decoration: none;
color: White;
background-color: #006;
margin: 0px 1px 0px 1px;
}
.pagerButtonDisabled
{
border: none;
color: #999;
padding: 1px;
}
这样一个分页连接就做好了,如果选择某一页的话就会根据路由参数去匹配分页
//路由参数
var routeData = new RouteValueDictionary { { "page", ViewData["PageIndex"].ToString() }, { "pageSize", Model.PageSize } };
但是仅仅有了分页链接还是不够的,分页连接是一个一个单独的,我们需要把他做成一个列表形式的控件
好下面我们就来创建分页控件。
创建分页控件
鼠标右击Shared文件夹--新建--视图
命名为_Pager,创建为EmployeeGridModel的强类型视图,选择分部视图,以便主页能调用他。
修改_Pager代码如下
@model MVC3.Grid.Models.EmployeeGridModel
<div>
@{
// 创建上一页链接
Html.RenderPartial("_PagerLink", Model,
new ViewDataDictionary {
{ "Text", "上一页" },
{ "PageIndex", Model.CurrentPageIndex - 1 },
{ "Selected", false },
{ "Inactive", Model.CurrentPageIndex == 1 }
});
//获取第一页和最后一页
var startPageIndex = Math.Max(1, Model.CurrentPageIndex - Model.PageCount / 2);
var endPageIndex = Math.Min(Model.PageCount, Model.CurrentPageIndex + Model.PageCount / 2);
// 添加中间的页码 如: 上一页 1 2 3 4 下一页
for (var i = startPageIndex; i <= endPageIndex; i++)
{
Html.RenderPartial("_PagerLink", Model,
new ViewDataDictionary {
{ "Text", i },
{ "PageIndex", i },
{ "Selected", i == Model.CurrentPageIndex },
{ "Inactive", i == Model.CurrentPageIndex }
});
}
// 创建下一页
Html.RenderPartial("_PagerLink", Model,
new ViewDataDictionary {
{ "Text", "下一页" },
{ "PageIndex", Model.CurrentPageIndex + 1 },
{ "Selected", false },
{ "Inactive", Model.CurrentPageIndex == Model.PageCount }
});
}
</div>
从上面的代码可以看出,我们的分页控件完全是由分页链接组成的,第一页和最后一页分部写了,中间的使用了遍历读取所有的分页。
给每个分页链接添加了参数,确保他们在_PagerLink中能够使用CSS及调用Action方法。
这样我们的一个简单的分页控件就做好了。下面我们要调用分页控件了。。
为Grid添加分页控件
回到我们Paged.cshtml,我们在最后的合并行添加一个分页控件,来完成我们表格的分页。
将空格改为调用_Pager即可。
<tr>
<td colspan="5">
@Html.Partial("_Pager", Model)
</td>
</tr>
运行效果
我们点击上下页,功能已经完成。
唯一的缺憾是我们的控件,在最后一页的时候就会缺少几行,有点丑。
我们可以对他进行美化填充
Paged.cshtml完整代码:
@model MVC3.Grid.Models.EmployeeGridModel
@{
ViewBag.Title = "Paged";
Layout = "~/Views/Shared/_Layout.cshtml";
int i = 0;
}
<h2>分页列表</h2>
<p>
<i>总共有 @Model.TotalRecordCount 条记录,每页显示 @Model.PageSize 条</i>
<i>你正在查看的是 @Model.PageCount 页的第 @Model.CurrentPageIndex 页</i>
</p>
<table border="1" width="100%" style="text-align: center; border-collapse: collapse">
<tr>
<th>编号</th>
<th>姓名</th>
<th>性别</th>
<th>生日</th>
<th>是否婚配</th>
</tr>
@foreach (var item in Model.Employees)
{
<tr>
<td>@item.EmployeeNO</td>
<td>@item.EmployName</td>
<td>@item.Sex</td>
<td>@string.Format("{0:yyyy年MM月dd日}",item.Birthday)</td>
<td>
@if (item.Marital == "1")
{
@:@("是")
}
@if (item.Marital != "1")
{
@:@("否")
}
</td>
</tr>
i++;
}
@if (i < 5)
{
while (i < Model.PageSize)
{
i++;
<tr>
<td colspan="5"> </td>
</tr>
}
}
<tr>
<td colspan="5">
@Html.Partial("_Pager", Model)
</td>
</tr>
</table>
美化效果
大功告成!!!
总结
MVC的分页控件,实际就是多个分页链接控件的组成,通过循环遍历等手段,将页数转换为分页连接,然后给每个链接指定Action的参数值,调用相应的Action操作方法,返回读取的数据集。这种方式虽然复杂,但是重用性很高,如果加以封装可以在任意程序中使用。
下节预告
下节我们将学习如何使用MVC原理来实现表格中数据的筛选
作者:记忆逝去的青春
出处:http://www.cnblogs.com/lukun/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,如有问题,可以通过http://www.cnblogs.com/lukun/ 联系我,非常感谢。