Enhanced PagedList for ASP.NET MVC
ASP.NET MVC已经发布了新的源代码,但不是官方版本。大家可以到http://codeplex.com/aspnet看看。
在实际项目中,肯定不会像Scottgu的demo那么简单。比如我们需要将数据分页显示。这的确是一个非常重要的功能。
MVCToolkit下一个版本会包含一个PagedList<T>支持数据分页,但我已经等不及了。
下面就是经过改进的分页类。
首先定义一个接口来包含我们需要的功能。
1 /// <summary>
2 /// 分页列表接口
3 /// </summary>
4 public interface IPagedList
5 {
6 int PageSize { get; set; }
7 int PageNumber { get; set; }
8
9 int TotalCount { get; }
10 int PageCount { get; }
11 bool HasPreviousPage { get; }
12 bool HasNextPage { get; }
13 }
14
2 /// 分页列表接口
3 /// </summary>
4 public interface IPagedList
5 {
6 int PageSize { get; set; }
7 int PageNumber { get; set; }
8
9 int TotalCount { get; }
10 int PageCount { get; }
11 bool HasPreviousPage { get; }
12 bool HasNextPage { get; }
13 }
14
现在实现PagedList<T>:
1 /// <summary>
2 /// 分页列表泛型类
3 /// </summary>
4 /// <typeparam name="T">集合元素类型</typeparam>
5 public class PagedList<T> : List<T>, IPagedList
6 {
7 /// <summary>
8 /// 利用现有的IQueryable<T>列表创建一个新的分页列表
9 /// </summary>
10 /// <param name="source">现有的元素集合</param>
11 /// <param name="page">页号</param>
12 /// <param name="pageSize">分页大小</param>
13 public PagedList(IQueryable<T> source, int page, int pageSize)
14 {
15 this.TotalCount = source.Count();
16 this.PageNumber = page;
17 this.PageSize = pageSize;
18
19 if (this.PageCount < page || page <= 0)
20 throw new ArgumentOutOfRangeException("page");
21
22 this.AddRange(source.Skip((page - 1) * pageSize).Take(pageSize).ToList());
23 }
24
25 /// <summary>
26 /// 利用现有的列表List<T>创建一个新的分页列表
27 /// </summary>
28 /// <param name="source">现有的元素集合</param>
29 /// <param name="page">页号</param>
30 /// <param name="pageSize">分页大小</param>
31 public PagedList(List<T> source, int page, int pageSize)
32 {
33 this.TotalCount = source.Count();
34 this.PageNumber = page;
35 this.PageSize = pageSize;
36
37 if (this.PageCount < page || page <= 0)
38 throw new ArgumentOutOfRangeException("page");
39
40 this.AddRange(source.Skip((page - 1) * pageSize).Take(pageSize).ToList());
41 }
42
43 /// <summary>
44 /// 获取表示列表元素总个数的整数
45 /// </summary>
46 public int TotalCount { get; private set; }
47
48 /// <summary>
49 /// 获取或设置一个表示当前页号的整数
50 /// </summary>
51 public int PageNumber { get; set; }
52
53 /// <summary>
54 /// 获取或设置一个整数来表示分页大小
55 /// </summary>
56 public int PageSize { get; set; }
57
58 /// <summary>
59 /// 获取一个表示总页数的整数
60 /// </summary>
61 public int PageCount
62 {
63 get
64 {
65 if (PageSize == 0)
66 throw new ArgumentOutOfRangeException("page");
67
68 int remainder = TotalCount % PageSize;
69
70 if (remainder == 0)
71 return TotalCount / PageSize;
72 else
73 return (TotalCount / PageSize) + 1;
74 }
75 }
76
77 /// <summary>
78 /// 获取一个布尔值表示当前页是否有上一页
79 /// </summary>
80 public bool HasPreviousPage
81 {
82 get
83 {
84 return (PageNumber - 1) > 0;
85 }
86 }
87
88 /// <summary>
89 /// 获取一个布尔值表示当前页是否有下一页
90 /// </summary>
91 public bool HasNextPage
92 {
93 get
94 {
95 return (PageNumber * PageSize) < TotalCount;
96 }
97 }
98 }
99
2 /// 分页列表泛型类
3 /// </summary>
4 /// <typeparam name="T">集合元素类型</typeparam>
5 public class PagedList<T> : List<T>, IPagedList
6 {
7 /// <summary>
8 /// 利用现有的IQueryable<T>列表创建一个新的分页列表
9 /// </summary>
10 /// <param name="source">现有的元素集合</param>
11 /// <param name="page">页号</param>
12 /// <param name="pageSize">分页大小</param>
13 public PagedList(IQueryable<T> source, int page, int pageSize)
14 {
15 this.TotalCount = source.Count();
16 this.PageNumber = page;
17 this.PageSize = pageSize;
18
19 if (this.PageCount < page || page <= 0)
20 throw new ArgumentOutOfRangeException("page");
21
22 this.AddRange(source.Skip((page - 1) * pageSize).Take(pageSize).ToList());
23 }
24
25 /// <summary>
26 /// 利用现有的列表List<T>创建一个新的分页列表
27 /// </summary>
28 /// <param name="source">现有的元素集合</param>
29 /// <param name="page">页号</param>
30 /// <param name="pageSize">分页大小</param>
31 public PagedList(List<T> source, int page, int pageSize)
32 {
33 this.TotalCount = source.Count();
34 this.PageNumber = page;
35 this.PageSize = pageSize;
36
37 if (this.PageCount < page || page <= 0)
38 throw new ArgumentOutOfRangeException("page");
39
40 this.AddRange(source.Skip((page - 1) * pageSize).Take(pageSize).ToList());
41 }
42
43 /// <summary>
44 /// 获取表示列表元素总个数的整数
45 /// </summary>
46 public int TotalCount { get; private set; }
47
48 /// <summary>
49 /// 获取或设置一个表示当前页号的整数
50 /// </summary>
51 public int PageNumber { get; set; }
52
53 /// <summary>
54 /// 获取或设置一个整数来表示分页大小
55 /// </summary>
56 public int PageSize { get; set; }
57
58 /// <summary>
59 /// 获取一个表示总页数的整数
60 /// </summary>
61 public int PageCount
62 {
63 get
64 {
65 if (PageSize == 0)
66 throw new ArgumentOutOfRangeException("page");
67
68 int remainder = TotalCount % PageSize;
69
70 if (remainder == 0)
71 return TotalCount / PageSize;
72 else
73 return (TotalCount / PageSize) + 1;
74 }
75 }
76
77 /// <summary>
78 /// 获取一个布尔值表示当前页是否有上一页
79 /// </summary>
80 public bool HasPreviousPage
81 {
82 get
83 {
84 return (PageNumber - 1) > 0;
85 }
86 }
87
88 /// <summary>
89 /// 获取一个布尔值表示当前页是否有下一页
90 /// </summary>
91 public bool HasNextPage
92 {
93 get
94 {
95 return (PageNumber * PageSize) < TotalCount;
96 }
97 }
98 }
99
再建立一个扩展类,就完成了添加分页功能。建议将这些类放在System.Web.Mvc命名空间下,这样就可以直接在您的项目中使用了:
1 /// <summary>
2 /// 分页列表扩展类
3 /// </summary>
4 public static class Pagination
5 {
6 /// <summary>
7 /// 将IQueryable<T>转换成分页列表PagedList<T>的一个实例
8 /// </summary>
9 /// <typeparam name="T">元素类型</typeparam>
10 /// <param name="source">要转换的集合,这里是LINQ结果集</param>
11 /// <param name="page">当前页号</param>
12 /// <param name="pageSize">分页大小</param>
13 /// <returns></returns>
14 public static PagedList<T> ToPagedList<T>(this IQueryable<T> source, int page, int pageSize)
15 {
16 return new PagedList<T>(source, page, pageSize);
17 }
18
19 /// <summary>
20 /// 使用默认分页大小(pageSize=10)将IQueryable<T>转换成分页列表PagedList<T>的一个实例,
21 /// </summary>
22 /// <typeparam name="T">元素类型</typeparam>
23 /// <param name="source">要转换的集合,这里是LINQ结果集</param>
24 /// <param name="page">当前页号</param>
25 /// <returns></returns>
26 public static PagedList<T> ToPagedList<T>(this IQueryable<T> source, int page)
27 {
28 return new PagedList<T>(source, page, 5);
29 }
30 }
31
2 /// 分页列表扩展类
3 /// </summary>
4 public static class Pagination
5 {
6 /// <summary>
7 /// 将IQueryable<T>转换成分页列表PagedList<T>的一个实例
8 /// </summary>
9 /// <typeparam name="T">元素类型</typeparam>
10 /// <param name="source">要转换的集合,这里是LINQ结果集</param>
11 /// <param name="page">当前页号</param>
12 /// <param name="pageSize">分页大小</param>
13 /// <returns></returns>
14 public static PagedList<T> ToPagedList<T>(this IQueryable<T> source, int page, int pageSize)
15 {
16 return new PagedList<T>(source, page, pageSize);
17 }
18
19 /// <summary>
20 /// 使用默认分页大小(pageSize=10)将IQueryable<T>转换成分页列表PagedList<T>的一个实例,
21 /// </summary>
22 /// <typeparam name="T">元素类型</typeparam>
23 /// <param name="source">要转换的集合,这里是LINQ结果集</param>
24 /// <param name="page">当前页号</param>
25 /// <returns></returns>
26 public static PagedList<T> ToPagedList<T>(this IQueryable<T> source, int page)
27 {
28 return new PagedList<T>(source, page, 5);
29 }
30 }
31
扩展完成。我们现在可以从LINQ数据集里创建PagedList了:
图1:将LINQ数据集转换为分页列表